python - 减少超出范围的数组

标签 python numpy

假设我有一个数字数组

np.array(([1, 4, 2, 1, 2, 5]))

我想计算切片列表的总和

((0, 3), (2, 4), (2, 6))

给予

[(1 + 4 + 2), (2 + 1), (2 + 1 + 2 + 5)]

在 numpy 中有没有好的方法可以做到这一点?

寻找相当于的东西

def reduce(a, ranges):
  np.array(list(np.sum(a[low:high]) for (low, high) in ranges))

似乎可能有一些奇特的 numpy 方法可以做到这一点。有人知道吗?

最佳答案

一种方法是使用np.add.reduceat 。如果a是值数组[1, 4, 2, 1, 2, 5]:

>>> np.add.reduceat(a, [0,3, 2,4, 2])[::2]
array([ 7,  3, 10], dtype=int32)

此处,切片索引在列表中传递,并求和以返回 [ 7, 1, 3, 2, 10] (即 a[0:3], a[3:], a[2:4], a[4:], a[2 :])。我们只想要这个数组中的所有其他元素。

<小时/>

更长的替代方法...

事实上,切片的长度不同,这使得在 NumPy 中进行矢量化有点棘手,但这是解决该问题的一种方法。

给定一个值数组和一个切片数组来制作...

a = np.array(([1, 4, 2, 1, 2, 5]))
slices = np.array([(0, 3), (2, 4), (2, 6)])

...创建一个类似于掩码的数组 z,对于每个切片,该数组将用于将 a 中的值“清零”,而我们不这样做想要求和:

z = np.zeros((3, 6))
s1 = np.arange(6) >= s[:, 0][:,None]
s2 = np.arange(6) < s[:, 1][:,None]
z[s1 & s2] = 1

然后你可以这样做:

>>> (z * a).sum(axis=1)
array([  7.,   3.,  10.])

快速的 %timeit 显示这比列表理解稍快,尽管我们必须构造 zz * a。如果 slices 的长度设为 3000,则此方法的速度大约快 40 倍。

但是请注意,数组 z 的形状为 (len(slices), len(a)),如果 aslices 都非常长 - 可能会首选迭代方法来避免内存中出现大型临时数组。

关于python - 减少超出范围的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28840360/

相关文章:

python - 在 Python 中创建具有多个给定值的掩码数组

python - 用python计算数据字符串中的nan

python - Django 按小时/天分组

python - 如何使用 python + NumPy/SciPy 计算滚动/移动平均值?

python - 3D 数组中一个轴上的滚动平均值

python - 不可变的 numpy 数组

python - Pytorch:为什么 `tensor`变量占用的内存这么小?

python - 如何在 Django 中建立 "One or Many"关系模型?

python - 如何在 GDAL Python 中获得带状数组的正确比例?

python - 为什么使用 setattr() 和 getattr() 内置函数?