我有两个相同形状的numpy数组。一个包含了我感兴趣的信息,另一个包含了一堆可以作为掩码值的整数。
从本质上讲,我想循环浏览每一个唯一的整数,得到数组的每一个掩码,然后用这个掩码对主数组进行过滤,并找到过滤后数组的最大值。
为了简单起见,让我们说数组是。
arr1 = np.random.rand(10000,10000)
arr2 = np.random.randint(low=0, high=1000, size=(10000,10000))
现在我正在做这个
maxes = {}
ids = np.unique(arr2)
for id in ids:
max_val = arr1[np.equal(arr2, id)].max()
maxes[id] = max_val
我的数组比较大,速度很慢,我正在努力寻找一种更快的方法... ...也许有一些我不知道的创新方法,真的很感谢任何帮助。
EDIT
假设arr2的大部分实际上是0,而我不在乎0的id,是否可以从搜索中放弃这整个块,从而加快搜索速度?
即
arr2[:, 0:4000] = 0
并只返回id的最大值> 0?
非常感谢...
下面列举了一些方法来处理这种需要我们执行基于bin的还原操作的场景。所以,本质上我们得到两个数组,我们需要使用一个数组作为bin,另一个数组作为值,并减少第二个数组。
方法#1 。 一种策略是将 arr1
基于 arr2
. 一旦我们将它们按同样的顺序排序,我们就会找到组的开始和停止指数,然后用适当的 ufunc.reduceat
,我们做我们的基于切片的减少操作。这就是全部了!
下面是我们的实现方法
def binmax(bins, values, reduceat_func):
''' Get binned statistic from two 1D arrays '''
sidx = bins.argsort()
bins_sorted = bins[sidx]
grpidx = np.flatnonzero(np.r_[True,bins_sorted[:-1]!=bins_sorted[1:]])
max_per_group = reduceat_func(values[sidx],grpidx)
out = dict(zip(bins_sorted[grpidx], max_per_group))
return out
out = binmax(arr2.ravel(), arr1.ravel(), reduceat_func=np.maximum.reduceat)
它适用于所有有相应的 ufunc.reduceat
方法。
方法2 : 我们也可以利用 scipy.stats.binned_statistic
这基本上是一个通用的工具来做一些常见的基于binned数组值的还原操作----。
from scipy.stats import binned_statistic
def binmax_v2(bins, values, statistic):
''' Get binned statistic from two 1D arrays '''
num_labels = bins.max()+1
R = np.arange(num_labels+1)
Mx = binned_statistic(bins, values, statistic=statistic, bins=R)[0]
idx = np.flatnonzero(~np.isnan(Mx))
out = dict(zip(idx, Mx[idx].astype(int)))
return out
out = binmax_v2(arr2.ravel(), arr1.ravel(), statistic='max')