我想了解这个ndarray.sum(axis =)是如何工作的。我知道axis = 0用于列,axis = 1用于行。 但是在3维(3轴)的情况下,很难解释下面的结果。
arr = np.arange(0,30).reshape(2,3,5)
arr
Out[1]:
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]],
[[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]]])
arr.sum(axis=0)
Out[2]:
array([[15, 17, 19, 21, 23],
[25, 27, 29, 31, 33],
[35, 37, 39, 41, 43]])
arr.sum(axis=1)
Out[8]:
array([[15, 18, 21, 24, 27],
[60, 63, 66, 69, 72]])
arr.sum(axis=2)
Out[3]:
array([[ 10, 35, 60],
[ 85, 110, 135]])
在这个 3轴阵列形状(2,3,5)的例子中,有3行5列。但是如果我整个看这个数组,看起来只有两行(都有3个数组元素)。
任何人都可以解释这个总和如何在3轴或更多轴(尺寸)的数组上工作。
答案 0 :(得分:6)
如果您想保留尺寸,可以指定keepdims
:
>>> arr = np.arange(0,30).reshape(2,3,5)
>>> arr.sum(axis=0, keepdims=True)
array([[[15, 17, 19, 21, 23],
[25, 27, 29, 31, 33],
[35, 37, 39, 41, 43]]])
否则,您从中求和的轴将从形状中移除。跟踪此问题的一种简单方法是使用numpy.ndarray.shape
属性:
>>> arr.shape
(2, 3, 5)
>>> arr.sum(axis=0).shape
(3, 5) # the first entry (index = axis = 0) dimension was removed
>>> arr.sum(axis=1).shape
(2, 5) # the second entry (index = axis = 1) was removed
如果需要,您还可以沿多个轴求和(按指定轴的数量减少维数):
>>> arr.sum(axis=(0, 1))
array([75, 81, 87, 93, 99])
>>> arr.sum(axis=(0, 1)).shape
(5, ) # first and second entry is removed
答案 1 :(得分:3)
这是解释这一点的另一种方式。您可以将多维数组视为张量T[i][j][k]
,而i,j,k分别代表轴0,1,2
。
T.sum(axis = 0)
在数学上等同于:
相似,T.sum(axis = 1)
:
而且,T.sum(axis = 2)
:
换句话说,轴将被总结,例如axis = 0
,第一个索引将被求和。如果用for循环写的话:
result[j][k] = sum(T[i][j][k] for i in range(T.shape[0])) for all j,k
代表axis = 1
:
result[i][k] = sum(T[i][j][k] for j in range(T.shape[1])) for all i,k
等
答案 2 :(得分:3)
numpy
将(2,3,5)数组显示为2个3x5数组(3行,5列)。或者称他们为'飞机' (MATLAB会将其显示为5个2x3的块)。
numpy
显示也匹配嵌套列表 - 两个子列表的列表;每个都有3个子列表。每个都是5个元素长。
在3x5 2d情况下,轴0沿3
维度求和,得到一个5元素数组。描述'对行的总结'或者'沿着colulmns'英语有点模糊。关注结果,形状的变化以及要求的总和,而不是描述。
回到3d案例:
使用axis=0
,它沿第一维求和,有效地删除它,留下3x5数组。 0+15=16, 1+16=17 etc
。
轴1,缩小尺寸3
尺寸,结果为2x5。 0+5+10=15, etc
。
轴2,缩小尺寸5
尺寸,结果为2x3,sum((0,1,2,3,4))
你的例子很好,因为3个维度是不同的,并且在总和中更容易看到哪个被消除了。
2d有些含糊不清; '总结行数' - 这是否意味着行被删除或保留?有了3d,没有歧义;如果轴= 0,则只能删除它,而另外2个。
答案 3 :(得分:0)
您指定的轴是有效移除的轴。因此,给定(2,3,5)
形状,轴0给出(3,5)
,轴1给出(2,5)
等。这可以扩展到任意数量的维度。
答案 4 :(得分:0)
您似乎对numpy数组的输出样式感到困惑。输出的“行”几乎总是 last 索引,而不是第一个。例如:
x=np.arange(1,4)
y=np.arange(10,31,10)
z=np.arange(100,301,100)
xy=x[:,None]+y[None,:]
xy
Out[100]:
array([[11, 21, 31],
[12, 22, 32],
[13, 23, 33]])
注意行上的十位增量,而不是列,即使y是第二个索引。
xyz=x[:,None,None]+y[None,:,None]+z[None,None,:]
xyz
Out[102]:
array([[[111, 211, 311],
[121, 221, 321],
[131, 231, 331]],
[[112, 212, 312],
[122, 222, 322],
[132, 232, 332]],
[[113, 213, 313],
[123, 223, 323],
[133, 233, 333]]])
现在行中的百位增量,即使z是最后一个索引。这对初学者来说可能有些违反直觉。
因此,当您执行np.sum(x,index=-1)
时,您将始终对“行”进行总结,如np.array([])
格式所示。查看arr.sum(axis=2)[0,0]
的{{1}}。
答案 5 :(得分:0)
将多维数组视为树。每个维度都是树中的一个级别。该级别的每个分组都是一个节点。沿特定轴的总和(比如轴= 4)意味着将该级别的所有节点合并(重叠)成单个节点(在它们各自的父节点下)。以该级别的重叠节点为根的子树堆叠在彼此之上。所有重叠节点'价值加在一起。
图片:https://ibb.co/dg3P3w
答案 6 :(得分:0)
使用更简单的3D阵列可能更容易看到。用1填充数组后,总和中的数字就是特定维数的总和!在每种情况下,其他两个维度均保持不变。
arr = np.arange(0,60).reshape(4,3,5)
arr
Out[10]:
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]],
[[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]],
[[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39],
[40, 41, 42, 43, 44]],
[[45, 46, 47, 48, 49],
[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59]]])
arr=arr*0+1
arr
Out[12]:
array([[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]]])
arr0=arr.sum(axis=0,keepdims=True)
arr2=arr.sum(axis=2,keepdims=True)
arr1=arr.sum(axis=1,keepdims=True)
arr0
Out[20]:
array([[[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4],
[4, 4, 4, 4, 4]]])
arr1
Out[21]:
array([[[3, 3, 3, 3, 3]],
[[3, 3, 3, 3, 3]],
[[3, 3, 3, 3, 3]],
[[3, 3, 3, 3, 3]]])
arr2
Out[22]:
array([[[5],
[5],
[5]],
[[5],
[5],
[5]],
[[5],
[5],
[5]],
[[5],
[5],
[5]]])