問題描述
假設我們有兩個簡單的陣列:
query = np.array([100, 4000, 500, 700, 400, 100])
match = np.array([6, 100, 4000, 100, 10, 8, 10])
我想找到查詢和匹配之間所有匹配值的索引。所以在這種情況下,結果將是:
value query match
100 0 1
100 0 3
100 5 1
100 5 3
4000 1 2
實際上,這些陣列將包含數百萬個專案
“愚蠢”的回圈解決方案
qs = []
query_locs = []
match_locs = []
for i in np.arange(query.size):
q = query[i]
# Get matching indexes in "match"
match_loc = np.where(match == q)[0]
n = match_loc.size
# Update location arrays
match_locs.extend(match_loc)
query_locs.extend(np.repeat(i,n))
# Store the matching value
qs.extend(np.repeat(q,n))
result = np.vstack((qs, query_locs, match_locs)).T
print(result)
[[ 100 0 1]
[ 100 0 3]
[4000 1 2]
[ 100 5 1]
[ 100 5 3]]
(也許numba可以使這個回圈非常快,但是當我嘗試這個時,我得到了一些關于簽名的錯誤,所以不確定)
Numpy 構建
有相當多的內置 numpy 函式可以解決唯一值的這個問題,例如使用searchsorted, intersect1d,但是,正如檔案中所述,它們“回傳排序的唯一值”,因此不考慮重復項。StackOverflow 上針對此問題的一些具有唯一值的示例:
- NumPy:比較兩個陣列中的元素
- 計算兩個numpy陣列之間相交值的有效方法
我可以想象會有一種更快的方法來使用 numpy 而不是回圈來做到這一點,所以很想看到答案!
uj5u.com熱心網友回復:
您可以將一維陣列轉換為資料幀并進行連接,如下所示:
query = np.array([100, 4000, 500, 700, 400, 100])
match = np.array([6, 100, 4000, 100, 10, 8, 10])
dfquery = pd.DataFrame(range(len(query)), index=query, columns=['query'])
dfmatch = pd.DataFrame(range(len(match)), index=match, columns=['match'])
dfquery.join(dfmatch, how='inner')
結果:
query match
100 0 1
100 0 3
100 5 1
100 5 3
4000 1 2
uj5u.com熱心網友回復:
你可以用 newaxis 破解它:
>>> comparison = np.equal(query[:, np.newaxis], match[np.newaxis, :])
array([[False, True, False, True, False, False, False],
[False, False, True, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, True, False, True, False, False, False]])
它本質上創建了笛卡爾積(queryx matches)(注意記憶體成本),然后應用二元函式np.equal將積空間中的每個元素轉換為bool有效的。輸出可以通過逐行讀取來解釋為:只要comparison[i, j]是,查詢元素 i 就等于匹配元素 j True。您可以使用以下方法收集所有True對的索引:
list(zip(*comparison.nonzero()))
[(0, 1), (0, 3), (1, 2), (5, 1), (5, 3)]
ps:如果陣列太長而無法構造產品,則按元素迭代它們是您唯一的選擇。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/410461.html
標籤:
