如何使用NumPy在每个行和列上应用我自己的函数

时间:2016-07-31 11:36:45

标签: python python-3.x numpy

我正在使用NumPy将数据存储到矩阵中。 我正在努力使下面的Python代码表现得更好。 RESULT是我想要将数据放入的数据存储。

TMP = np.array([[1,1,0],[0,0,1],[1,0,0],[0,1,1]])
n_row, n_col = TMP.shape[0], TMP.shape[0]
RESULT = np.zeros((n_row, n_col))

def do_something(array1, array2):
    intersect_num = np.bitwise_and(array1, array2).sum()
    union_num = np.bitwise_or(array1, array2).sum()
    try:
        return intersect_num / float(union_num)
    except ZeroDivisionError:
        return 0

for i in range(n_row):
    for j in range(n_col):
    if i >= j:
        continue
    RESULT[i, j] = do_something(TMP[i], TMP[j])

我想如果我可以使用一些NumPy内置函数而不是for-loops会更快。

我正在寻找这里的各种问题,但我找不到最适合我的问题。 有什么建议吗?提前谢谢!

1 个答案:

答案 0 :(得分:1)

方法#1

你可以做这样的事情作为矢量化解决方案 -

# Store number of rows in TMP as a paramter
N = TMP.shape[0]  

# Get the indices that would be used as row indices to select rows off TMP and 
# also as row,column indices for setting output array. These basically correspond
# to the iterators involved in the loopy implementation
R,C = np.triu_indices(N,1)    

# Calculate intersect_num, union_num and division results across all iterations
I = np.bitwise_and(TMP[R],TMP[C]).sum(-1)
U = np.bitwise_or(TMP[R],TMP[C]).sum(-1)
vals = np.true_divide(I,U)

# Setup output array and assign vals into it
out = np.zeros((N, N))
out[R,C] = vals

方法#2

对于TMP持有1s0s的案例,np.bitwise_andnp.bitwise_or可以替换为点积,因此可能是更快的替代品。那么,有了那些我们就会有这样的实现 -

M = TMP.shape[1]   
I = TMP.dot(TMP.T)
TMP_inv = 1-TMP
U = M - TMP_inv.dot(TMP_inv.T)
out = np.triu(np.true_divide(I,U),1)