我是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])
它是如何产生的?有人能解释一下吗?
答案 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=1
和 i+1=3
因此我们将得到一个切片 array[1:3]
,它们是元素 1, 2
,总和为 3。然后我们得到一个从 i=3
到 i+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=0
到i+1=4
开头,即。它采用前 4 个元素并返回它们的总和 0+1+2+3=6
。现在需要 i=4
到 i+1=1
,正如评论中提到的,如果尝试会产生 []
。但是,再次回忆一下文档:
如果索引[i] >=索引[i + 1],第i个广义“行”就是数组[索引[i]]
这意味着我们只得到一个元素,即。 4
。之后,我们再次像第一种情况一样继续对 4 个元素求和,然后再次给出一行 = 一个元素,5
等。
从上面的例子中可能已经看到,我们得到了线性上升,然后当我们需要从 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=0
到 i+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
),因为它们完全相同。希望有帮助。