在python中numpy reduceat()的含义是什么?

时间:2014-06-20 18:13:17

标签: python numpy

我是Python的新手,我现在只是阅读教程。

我对reduceat()功能感到困惑。

我看到了这个例子:

np.add.reduceat([0,1,2,3,4,5,6,7],[0,4,1,5,2,6,3,7])[::2]

结果是:

array([ 6, 10, 14, 18])

它是如何产生的?有人能解释一下吗?

3 个答案:

答案 0 :(得分:2)

以上答案是正确的,但无法解释.reduceat实际在做什么! 基本上,它返回的是切片数组中元素的总和

例如:

array = np.arange(10)
indices = np.array([1,3,4,5])
output = numpy.add.reduceat(array,indices)  
print(output)

输出: [3 3 4 35]

幕后发生的事情是,它在数组上重复应用.reduce(),如下所示:

print("Step1 : ", np.add.reduce(array[1:3]))
print("Step2 : ", np.add.reduce(array[3:4]))
print("Step3 : ", np.add.reduce(array[4:5]))
print("Step4 : ", np.add.reduce(array[5:]))

,并将每个步骤的结果附加到列表中并显示结果!希望您了解调用numpy.add.reduceat()函数时实际发生的情况! 我并不是说上述答案是错误的,只是提供另一种解释以更好地理解该功能! 希望这可以帮助!谢谢!

答案 1 :(得分:1)

有点像滚动申请,请参阅:

In [59]:

np.add.reduceat([0,1,2,3,4,5,6,7],[0,4])
Out[59]:
array([ 6, 22])
In [65]:

np.add.reduceat([0,1,2,3,4,5,6,7],[4,1])
Out[65]:
array([ 4, 28])
In [66]:

np.add.reduceat([0,1,2,3,4,5,6,7],[1,5])
Out[66]:
array([10, 18])
In [64]:

np.add.reduceat([0,1,2,3,4,5,6,7],[5,2])
Out[64]:
array([ 5, 27])
In [61]:

np.add.reduceat([0,1,2,3,4,5,6,7],[2,6])
Out[61]:
array([14, 13])
In [67]:

np.add.reduceat([0,1,2,3,4,5,6,7],[6,3])
Out[67]:
array([ 6, 25])
In [62]:

np.add.reduceat([0,1,2,3,4,5,6,7],[3,7])
Out[62]:
array([18,  7])

如果你只想要第一个值,你可以一次性完成它:

In [63]:

np.add.reduceat([0,1,2,3,4,5,6,7],[0,4,1,5,2,6,3,7])
Out[63]:
array([ 6,  4, 10,  5, 14,  6, 18,  7])

答案 2 :(得分:0)

我也很难理解这个例子,我觉得这两个帖子仍然缺少一些东西,在一些评论中部分解释了所以让我也试着解释一下。

一般功能

documentation中所述,

<块引用>

对于范围内的 i(len(indices)),reduceat 计算 ufunc.reduce(array[indices[i]:indices[i+1]])

这意味着 reduceat 遍历给定列表中的所有索引,然后对数组执行给定的 ufunc 切片(这里是 add 数字)。

升序指数

@Adarsh_V_Desai 对此进行了非常详细的描述,@CT Zhu 也展示了这一点。遵循答案和示例:

import numpy as np
array = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
indices = np.array([1,3,4,5])

在循环的第一步中,i=1i+1=3 因此我们将得到一个切片 array[1:3],它们是元素 1, 2,总和为 3。然后我们得到一个从 i=3i+1=4 的切片,这只是一个元素 3。下一个元素也是如此,4。最后,我们从 i=5 到最后,因为没有其他索引(回忆文档:

<块引用>

对于最后一个索引,indices[i+1] = array.shape[axis]`),

产生 array[5:] 和元素 5, 6, 7, 8, 9,总和为 35。

降序索引

问题来了,当我们没有升序或降序索引时会发生什么。该原理的工作原理相同,并将建立到问题中原始示例的方法。让我们举个例子:

np.add.reduceat([0,1,2,3,4,5,6,7],[0,4,1,5,2,6,3,7])

如上图,以i=0i+1=4开头,即。它采用前 4 个元素并返回它们的总和 0+1+2+3=6。现在需要 i=4i+1=1,正如评论中提到的,如果尝试会产生 []。但是,再次回忆一下文档:

<块引用>

如果索引[i] >=索引[i + 1],第i个广义“行”就是数组[索引[i]]

这意味着我们只得到一个元素,即。 4。之后,我们再次像第一种情况一样继续对 4 个元素求和,然后再次给出一行 = 一个元素,5 等。

为什么 [::2]

从上面的例子中可能已经看到,我们得到了线性上升,然后当我们需要从 4 返回到 1 时跳转。我们得到单个元素,因为我们在索引列表中有降序跳转。而这正是 [::2] 正在删除的内容 -> 它只获取第二个元素,并且由于我们每隔一个位置就有这些跳转,我们从结果中删除它们。

二维数组

你没有问,但我相信提到它也有效(因为我一开始也很挣扎)。

x = np.linspace(0, 15, 16).reshape(4,4)
np.add.reduceat(x, [0, 3, 1, 2, 0])
array([[12.,  15.,  18.,  21.],
       [12.,  13.,  14.,  15.],
       [ 4.,   5.,   6.,   7.],
       [ 8.,   9.,  10.,  11.],
       [24.,  28.,  32.,  36.]])

这个可怕的生物所做的与上面描述的完全相同。首先,它需要从 i=0i+1=3 的索引(行!),即

[ 0.,   1.,   2.,   3.],
[ 4.,   5.,   6.,   7.],
[ 8.,   9.,  10.,  11.],

将它们相加并将它们放入第一行(您可以检查)。然后它跳了起来,因此你只得到一行,即第 4 行。然后它给你行数的总和 1:2 这只是第二行,所以你得到了那个。然后又一次从 i=2 跳转到 i+1=0,它也只是一行,在本例中是第三行。最后,它给出了所有行的总和,因为你从 0 到最后。

我不会讨论列 (axis=1),因为它们完全相同。希望有帮助。

相关问题