NumPy - 迭代2D列表并打印(行,列)索引

5
我在使用NumPy和/或Pandas处理2D列表时遇到了困难,需要做到以下几点:
  1. 获取所有元素的唯一组合的总和,不能再从同一行选择(对于下面的数组,应该有81种组合)。

  2. 打印组合中每个元素的行和列。

例如:

arr = [[1, 2, 4], [10, 3, 8], [16, 12, 13], [14, 4, 20]]

(1,3,12,20), Sum = 36 and (row, col) =  [(0,0),(1,1),(2,1),(3,2)]

(4,10,16,20), Sum = 50 and (row, col) =[(0,2),(1,0),(2,0),(3,2)]

我尝试了普通的Python for循环。但是我需要使用来自numpy/panda的高性能数据结构。我搜索了很多论坛,但找不到如何遍历所有元素组合的方法。 - vkb
2个回答

5

通过创建所有这样的组合并求和来实现: 这里是一个使用itertools.product数组索引的矢量化方法 -

from itertools import product

a = np.asarray(arr)  # Convert to array for ease of use and indexing
m,n = a.shape
combs = np.array(list(product(range(n), repeat=m)))
out = a[np.arange(m)[:,None],combs.T].sum(0)

样例运行 -

In [296]: arr = [[1, 2, 4], [10, 3, 8], [16, 12, 13], [14, 4, 20]]

In [297]: a = np.asarray(arr)
     ...: m,n = a.shape
     ...: combs = np.array(list(product(range(n), repeat=m)))
     ...: out = a[np.arange(m)[:,None],combs.T].sum(0)
     ...: 

In [298]: out
Out[298]: 
array([41, 31, 47, 37, 27, 43, 38, 28, 44, 34, 24, 40, 30, 20, 36, 31, 21,
       37, 39, 29, 45, 35, 25, 41, 36, 26, 42, 42, 32, 48, 38, 28, 44, 39,
       29, 45, 35, 25, 41, 31, 21, 37, 32, 22, 38, 40, 30, 46, 36, 26, 42,
       37, 27, 43, 44, 34, 50, 40, 30, 46, 41, 31, 47, 37, 27, 43, 33, 23,
       39, 34, 24, 40, 42, 32, 48, 38, 28, 44, 39, 29, 45])

节省内存的方法:这是一种不需要创建所有组合的方法,而是使用即时广播求和,其哲学非常受到这篇其他文章的启发 -

a = np.asarray(arr)
m,n = a.shape
out = a[0]
for i in range(1,m):
    out = out[...,None]  + a[i]
out.shape = out.size # Flatten

1
您可以使用`itertools`中的`product`函数:
from itertools import product    
y = [sum(p) for p in product(*arr)]

len(y)
# 81

一个带有较小列表的示例:
arr = [[1,2],[3,4],[5,6]]
[sum(p) for p in product(*arr)]
# [9, 10, 10, 11, 10, 11, 11, 12]

谢谢,它没有打印出导致该总和的元素的(row,col)索引。我该怎么做? - vkb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接