获得许多掩码的每个掩码 np.array 最大值的最快方法?

fastest way to get max value of each masked np.array for many masks?

我有两个相同形状的 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

我的数组大了很多,而且速度非常慢,我正在努力寻找一种更快的方法...也许有某种我不知道的创造性方法,非常感谢任何帮助。

编辑

假设 arr2 的大部分实际上是 0 而我不关心 0 id,是否可以通过从搜索中删除整个块来加快速度?

arr2[:, 0:4000] = 0

并且只是 return ID > 0 的最大值??

非常感谢..

基于 bin 的通用缩减策略

下面列出了一些解决我们需要执行基于 bin 的缩减操作的场景的方法。所以,基本上我们有两个数组,我们需要使用一个作为 bins,另一个作为值,并减少第二个。

方法 #1: 一种策略是根据 arr2arr1 进行排序。一旦我们以相同的顺序对它们进行排序,我们就会找到组的开始和停止索引,然后使用适当的 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 方法的 ufunc。

方法 #2: 我们还可以利用 scipy.stats.binned_statistic,它基本上是一个通用实用程序,可以根据分箱数组值执行一些常见的归约操作 -

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')