基于参考n维数组对n维数组进行操作的最有效方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于参考n维数组对n维数组进行操作的最有效方法相关的知识,希望对你有一定的参考价值。
我有两个相同形状的Numpy数组:dat_ara
和ref_ara
。
我想对op_func
的axis = -1
执行操作dat_ara
,但是我只想对每个数组中选定的值切片进行操作,当超过阈值thres
时指定切片通过参考数组ref_ara
。
为了说明,在简单的情况下,数组只是2维,我有:
thres = 4
op_func = np.average
ref_ara = array([[1, 2, 1, 4, 3, 5, 1, 5, 2, 5],
[1, 2, 2, 1, 1, 1, 2, 7, 5, 8],
[2, 3, 2, 5, 1, 6, 5, 2, 7, 3]])
dat_ara = array([[1, 0, 0, 1, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 1, 0],
[1, 0, 1, 1, 1, 1, 0, 1, 1, 1]])
[我们看到在thres
的axis=0
中的第一,第二和第三数组的第五,第七和第三索引中违反了ref_ara
。因此,我想要的结果将是
out_ara = array([op_func(array([1, 0, 0, 1, 1, 1]),
op_func(array([1, 1, 1, 1, 1, 1, 1, 0]),
op_func(array([1, 0, 1, 1])])
此问题很困难,因为它需要参考ref_ara
。如果不是这种情况,我可以简单地使用numpy.apply_along_axis
。
我已经尝试扩展两个数组的维,以将它们关联以进行计算,即:
assos_ara = np.append(np.expand_dims(dat_ara, axis=-1), np.expand_dims(ref_ara, axis=-1), axis=-1)
但是同样,numpy.apply_along_axis
要求输入函数只能在1维数组上运行,因此我仍然无法使用该函数。
我知道的另一种方法是明智地遍历数组索引,但是,由于数组的两个数组的尺寸不断变化,这是一件棘手的事,而且,它的计算效率也不高。
我想尽可能地使用矢量化函数来辅助此过程。最有效的方法是什么?
这是掩码数组的一个很好的用例,因为它们使您可以对部分数据执行常规的numpy操作。
假设每一行至少包含一个大于阈值的值。您可以通过以下方式计算断点的索引:
breaks = np.argmax(ref_ara > thres, axis=-1) # 5, 7, 3
mask = np.arange(ref_ara.shape[-1]) <= breaks.reshape(*breaks.shape, 1)
这里,我们不需要对
arange
进行任何处理,因为它位于最后一个维度上。如果不是这种情况,您可能想要在范围将要到达的中断形状中插入1,并在范围的尾部也填充一个。
现在,掩码数组和ufunc解决方案略有不同。掩码数组的版本更为通用,因此它是第一个:
data = np.ma.array(data_ara, mask=~mask)
掩码数组从普通布尔索引的作用向后解释掩码,因此我们将掩码反转。或者,您可以使用
>
而不是<=
计算掩码。现在的计算很简单:
out_ara = np.ma.average(data, axis=-1).data
一种不太通用的替代方法是将您的操作分解为ufunc,并使用它们提供的屏蔽。对于
np.average
(仅是np.average
和np.sum
),这很容易,但是对于更复杂的操作可能会更困难。
自numpy 1.17.0起,np.sum
具有np.divide
关键字:
np.divide
以上是关于基于参考n维数组对n维数组进行操作的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章