好奇(对我来说)在numpy数组中切片的行为

时间:2018-06-08 13:38:29

标签: python arrays numpy

这个小python代码:

   >>> a=np.random.rand(3,4,5)
   >>> a[0][:][3]
   >>> a[0,:,3]

产生结果:

array([[[ 0.19080354,  0.45701919,  0.17411363,  0.45117827,  0.10413359],
            [ 0.86430848,  0.81831987,  0.27604238,  0.25587538,  0.72733844],
            [ 0.42065355,  0.63994284,  0.64540483,  0.55639512,  0.4455423 ],
            [ 0.04778727,  0.53506934,  0.79615599,  0.24200543,  0.82332594]],
           [[ 0.36535239,  0.5973006 ,  0.71075267,  0.16814739,  0.26409851],
            [ 0.85557313,  0.54190805,  0.65531428,  0.80448208,  0.54959253],
            [ 0.62112884,  0.9159606 ,  0.10186144,  0.14956198,  0.38026561],
            [ 0.70577261,  0.02682898,  0.04136858,  0.15603152,  0.47125989]],
           [[ 0.72864857,  0.09365008,  0.84137507,  0.43887926,  0.26616441],
            [ 0.31022073,  0.54251517,  0.30635049,  0.36270005,  0.85149399],
            [ 0.39371669,  0.38230285,  0.77115029,  0.22647156,  0.57128166],
            [ 0.54906932,  0.87058929,  0.72157733,  0.79480009,  0.033705  ]]])
array([ 0.04778727,  0.53506934,  0.79615599,  0.24200543,  0.82332594])
array([ 0.45117827,  0.25587538,  0.55639512,  0.24200543])

为什么最后两行a[0][:][3]a[0,:,3]不返回数组的相同切片?我希望他们都能归还a[0,:,3]的内容。

3 个答案:

答案 0 :(得分:2)

a[0][:][3]说:取第0个(子)数组,第三行,相当于a[0][3]

a[0,:,3]说:取第0个(子)数组,所有行,第三个元素(列)

答案 1 :(得分:2)

每个[]由Python解释器单独评估,例如

In [117]: a=np.random.rand(3,4,5)
In [118]: a[0]
Out[118]: 
array([[0.98688694, 0.77224477, 0.19871568, 0.00552212, 0.81546143],
       [0.70685734, 0.72900717, 0.77127035, 0.07404465, 0.35846573],
       [0.11586906, 0.86310343, 0.62329813, 0.33089802, 0.06355835],
       [0.31098232, 0.32518332, 0.72960618, 0.63755747, 0.88721274]])
In [119]: _[:]
Out[119]: 
array([[0.98688694, 0.77224477, 0.19871568, 0.00552212, 0.81546143],
       [0.70685734, 0.72900717, 0.77127035, 0.07404465, 0.35846573],
       [0.11586906, 0.86310343, 0.62329813, 0.33089802, 0.06355835],
       [0.31098232, 0.32518332, 0.72960618, 0.63755747, 0.88721274]])
In [120]: _[3]
Out[120]: array([0.31098232, 0.32518332, 0.72960618, 0.63755747, 0.88721274])

使尾随切片显式(为了我们人类的清晰度):

In [121]: a[0,:,:][:,:][3,:]
Out[121]: array([0.31098232, 0.32518332, 0.72960618, 0.63755747, 0.88721274])

中间[:]未选择原始a中的维度。它根据a[0,:,:]的结果运行,并且什么都不做(除了创建一个具有相同形状和数据的新数组)。最后一个[3]未从a的第三维中进行选择 - 它从[:]步骤中获取的数组的第一维中进行选择。请注意,它返回一个shape(5,)数组,即a的最后一个维度的大小。 a[0,3,:]产生同样的事情。

另一方面,这完全由numpy索引处理,并同时处理所有3个维度:

In [122]: a[0,:,3]
Out[122]: array([0.00552212, 0.07404465, 0.33089802, 0.63755747])

返回形状(4,),a的中间维度。 a[0,:,:][:,3]产生同样的事情。

关键是numpy在Python解释器中运行;它不会改变Python语法。

答案 2 :(得分:1)

这是因为[:]没有对数组进行任何更改,因此a[0][:][3]a[0][3]相同,等于a[0, 3, :]