@memecs 解决方案是正确的,+1。但是,如果input_1 中的值非常大,即它们不是数组的索引,而是说它们是秒或其他可以取非常大值的整数数据,它将非常慢并且占用大量内存。
在这种情况下,np.bincount(input_1[input_2]).size 等于 input_1 中的最大整数,True 值在 input_2 中。
使用unique 和bincount 会快得多。我们使用第一个提取input_1的唯一元素的索引,然后使用bincount计算这些索引在同一个数组中出现的频率,并根据1或0的值对它们进行加权数组input_2(True 或False):
# extract unique elements and the indices to reconstruct the array
unq, idx = np.unique(input_1, return_inverse=True)
# calculate the weighted frequencies of these indices
freqs_idx = np.bincount(idx, weights=input_2)
# reconstruct the array of frequencies of the elements
frequencies = freqs_idx[idx]
print(frequencies)
此解决方案非常快,并且对内存的影响最小。归功于@Jaime,请参阅下面的评论。下面我报告我的原始答案,以不同的方式使用unique。
其他可能性
使用unique 寻求其他解决方案可能会更快:
import numpy as np
input_1 = np.array([3, 6, 6, 3, 6, 4])
input_2 = np.array([False, True, True, False, False, True])
non_zero_hits, counts = np.unique(input_1[input_2], return_counts=True)
all_hits, idx = np.unique(input_1, return_inverse=True)
frequencies = np.zeros_like(all_hits)
#2nd step, with broadcasting
idx_non_zero_hits_in_all_hits = np.where(non_zero_hits[:, np.newaxis] - all_hits == 0)[1]
frequencies[idx_non_zero_hits_in_all_hits] = counts
print(frequencies[idx])
这有一个缺点,如果在input_2 中具有True 值的input_1 中的唯一元素的数量很多,则它将需要大量内存,因为创建并传递给where 的二维数组.为了减少内存占用,您可以使用 for 循环代替算法的第二步:
#2nd step, but with a for loop.
for j, val in enumerate(non_zero_hits):
index = np.where(val == all_hits)[0]
frequencies[index] = counts[j]
print(frequencies[idx])
第二种解决方案的内存占用非常小,但需要for 循环。这取决于您的典型数据输入大小和值,哪种解决方案最好。