A[np.array(list1)[:,np.newaxis], np.array(list2)]
憑藉先進的索引如果arr1
和arr2
是NDarrays,的A[arr1, arr2]
的(i,j)
分量等於
A[arr1[i,j], arr2[i,j]]
因此,您希望arr1[i,j]
等於list1[i]
所有j
和 arr2[i,j]
等於list2[j]
所有i
。
可以在broadcasting(見下文)的幫助下設置 arr1 = np.array(list1)[:,np.newaxis]
和arr2 = np.array(list2)
。
的arr1
形狀(len(list1), 1)
而arr2
形狀是 (len(list2),)
因爲需要時新的軸被添加上自動左 ,其廣播到(1, len(list2))
。
每個陣列可以進一步廣播以形成(len(list1),len(list2))
。 這正是我們想要的 A[arr1[i,j],arr2[i,j]]
是有意義的,因爲我們希望(i,j)
運行於形狀爲(len(list1),len(list2))
的結果數組的所有可能的索引。
下面是這表明A[list1, :][:, list2]
是最快的選項微基準爲一個測試用例:
In [32]: %timeit orig(A, list1, list2)
10 loops, best of 3: 110 ms per loop
In [34]: %timeit using_listener(A, list1, list2)
1 loop, best of 3: 1.29 s per loop
In [33]: %timeit using_advanced_indexing(A, list1, list2)
1 loop, best of 3: 1.8 s per loop
這裏是我以前爲基準設置:
import numpy as np
import scipy.sparse as sparse
import random
random.seed(1)
def setup(N):
A = sparse.rand(N, N, .1, format='lil')
list1 = np.random.choice(N, size=N//10, replace=False).tolist()
list2 = np.random.choice(N, size=N//20, replace=False).tolist()
return A, list1, list2
def orig(A, list1, list2):
return A[list1, :][:, list2]
def using_advanced_indexing(A, list1, list2):
B = A.tocsc() # or `.tocsr()`
B = B[np.array(list1)[:, np.newaxis], np.array(list2)]
return B
def using_listener(A, list1, list2):
"""https://stackoverflow.com/a/26592783/190597 (listener)"""
B = A.tocsr()[list1, :].tocsc()[:, list2]
return B
N = 10000
A, list1, list2 = setup(N)
B = orig(A, list1, list2)
C = using_advanced_indexing(A, list1, list2)
D = using_listener(A, list1, list2)
assert np.allclose(B.toarray(), C.toarray())
assert np.allclose(B.toarray(), D.toarray())
list1和list2的內容是什麼?什麼給A [list1:list2]? – Louis
list1和list 2是包含整數的python列表對象,例如[1,4,6,8] A [list1:list2]爲空(<1x3稀疏矩陣的類型爲''\t,其中0個存儲元素以L列表格式> –
user972858