我正在使用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会更快。
我正在寻找这里的各种问题,但我找不到最适合我的问题。 有什么建议吗?提前谢谢!
答案 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
持有1s
和0s
的案例,np.bitwise_and
和np.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)