我试图理解为什么ndarray的平面迭代器可以正常工作。让A
成为一个形状为(N, N)
的ndarray。
A.flat[::N + 1] = 1
将A
的对角线元素设置为值1
。因此,A.flat
就像A
的观点一样行事。但令人惊讶的是,
A.flat[::N + 1][1:] = 1
不会修改A
(就像A.flat是一个视图一样)。
A.flat
是flatiter
对象,而不是A
的视图。这背后的理由是什么?是否可以将其作为一种观点来实现?
[据我所知,原始数组数据与有关数据解释的信息分开存储 - 数组长度,数组尺寸,步幅,列顺序等。所以似乎可以通过以下方式实现扁平化设置适当的尺寸(和步幅,取决于列顺序)。]
答案 0 :(得分:2)
在python中,A[a][b] = B
大致翻译为:
tmp = A[a]
tmp[b] = B
这适用于python对象,即列表或列表的列表,但它对于numpy数组是有问题的。当A[a]
是A
的视图时,它适用于numpy数组,但在A[a]
复制时不起作用。 This page会告诉你更多关于索引numpy数组何时返回视图以及何时返回副本的信息。我认为索引flat
属性始终返回一个副本。话虽如此,当您使用numpy数组时,我会在[]
的左侧避免两组=
。
更新: 您的问题的答案是“是否可以将[平面属性]实现为视图?”没有。 Numpy数组支持任意步幅,对于许多步幅组合,不可能创建平面数组的1d视图。如果可能,ravel方法将返回数组的视图。当无法将阵列展平为视图时,它将返回副本。我想如果你确定你的数组可以用视图展平,你可以做类似的事情:
A.ravel()[::N + 1][1:] = 1