<p>我喜欢使用<code>__array_interface__</code>来检查数组的属性:</p>
<p>用你的<code>x</code>:</p>
<pre><code>In [51]: x.__array_interface__
Out[51]:
{'data': (43241792, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (3, 3, 3),
'version': 3}
In [52]: x.strides
Out[52]: (72, 24, 8)
</code></pre>
<p>这是一个(3,3,3)数组。最后一个轴可以一次扫描8个字节,大小为<code>x.itemsize</code>。3*8步行,3*3*8步穿过平面(第一个尺寸)。你知道吗</p>
<pre><code>In [53]: y = x[:,1,2]
In [54]: y.shape
Out[54]: (3,)
In [55]: y.strides
Out[55]: (72,)
In [56]: y.__array_interface__['data']
Out[56]: (43241832, False)
</code></pre>
<p><code>y</code>元素可以通过平面3*3*8步进来寻址。43241832是起点,40字节进入数据缓冲区,5*8</p>
<pre><code>In [59]: y
Out[59]: array([ 5, 14, 23])
</code></pre>
<p>所以它从第5个元素开始,一次前进一个平面(9个元素),总共3个元素。你知道吗</p>
<p><code>y.__array_interface__['data']</code>在<code>x</code>“data”范围内的事实告诉我<code>y</code>是一个视图。这是一个视图,因为这个缓冲区起点、跨步和形状的组合允许我们访问<code>y</code>的所有值。你知道吗</p>
<p>使用高级索引,通常不可能用这些简单的参数访问元素,因此<code>numpy</code>必须复制数据。你知道吗</p>
<hr/>
<p>只需改变步幅和“数据”起点,就可以得到相反的观点:</p>
<pre><code>In [60]: z = y[::-1]
In [61]: z.__array_interface__
Out[61]:
{'data': (43241976, False),
'strides': (-72,),
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (3,),
'version': 3}
</code></pre>
<p>转置也会改变步伐:</p>
<pre><code>In [62]: x.T.strides
Out[62]: (8, 24, 72)
</code></pre>