如何对numpy数组的每两列执行一次操作?

时间:2012-02-26 08:58:48

标签: python numpy

现在我有一个NumPy数组01,我想在每个两个logical_and >列。实现此目的的for循环如下所示:

import numpy as np
result = []
data = [[0, 1, 1],
        [1, 0, 1],
        [1, 0, 1]]
np_data = np.array(data)
num_cols = len(np_data[1,:])
for i in range(0, num_cols):
    for j in range(i+1, num_cols):
        #Comparing every column with every other column
        anded = np.logical_and(np_data[:,i], np_data[:,j])
        result.append(anded)
print result

我只是想知道是否有NumPy - fied方法来执行此操作,因为显然for循环不适合在NumPy数组上操作。

3 个答案:

答案 0 :(得分:1)

你可以这样做,注意结果是你的结果的转置(在这种情况下,结果是一个二维数组,在你的情况下,它是一个1darrays的列表)。

>>> from itertools import combinations
>>> I, J = np.array(list(combinations([0,1,2], 2))).T
>>> result = np.logical_and(np_data[:, I], np_data[:, J])
>>> result
array([[False, False,  True],
       [False,  True, False],
       [False,  True, False]], dtype=bool)
>>> result.T
array([[False, False, False],
       [False,  True,  True],
       [ True, False, False]], dtype=bool)

答案 1 :(得分:0)

我确信有一种更聪明的方法来构建索引列表ii,jj,但这与您的示例代码相同:

import numpy as np
data = [[0, 1, 1],
       [1, 0, 1],
       [1, 0, 1]]
np_data = np.array(data)
q=range(len(data))
ii,jj=zip(*[[i,j] for i in q for j in q if i<j])
result=np.transpose(np.logical_and(np_data[:,list(ii)],np_data[:,list(jj)]))

编辑:对于ii,jj,您也可以使用此功能(受Bago启发):

ii,jj = np.array(list(combinations(q, 2))).T

答案 2 :(得分:0)

假设您有一个包含n行和m列的数组(n,m),那么您可以将逻辑和所有可能的列作为数组(m,m)获取,其中每个元素都是大小为n的数组。这与您的结果类似,但是尺寸加倍(没有三角矩阵)。

import numpy as np
data = np.array([[0, 1, 1],
                 [1, 0, 1],
                 [1, 0, 1]])
n,m = data.shape
dist0 = np.tile(data.T,(m,1)).reshape(m,m,n) # repeat columns along axis 0
dist1 = np.tile(data.T,(1,m)).reshape(m,m,n) # repeat columns along axis 1
result = np.logical_and(dist0, dist1)
# now result[i,j] contains the logical_and bewteen column i and j
print(result[0,2])
[False  True  True]