NumPy花式索引和赋值

12

通常情况下,numpy强制赋值左右两边的形状相同。例如,如果我执行a[:] = b,则b必须具有与a相同的形状或可广播到与a相同的形状。但是,这个规则似乎有例外:

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = a.copy()
>>> a[[0,1,2]] = b[::2]
>>> a
array([0, 2, 4, 3, 4, 5, 6, 7, 8, 9])
>>> a[np.arange(10)] = b[:2]
>>> a
array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1])

看起来它只适用于1d数组,并且只有在赋值的左侧使用花式索引时才有效,但我无法在任何地方找到关于这种行为的文档。如果有文档,请问在哪里可以找到,并且是否能给出一个有用的示例?

更新:

似乎numpy中的flatiter类型也是这样工作的,是否存在flatiter和花式索引之间的某种连接,我不知道吗?

>>> a.flat = [10,11]
>>> a
array([10, 11, 10, 11, 10, 11, 10, 11, 10, 11])
>>> a.flat[:] = [2,3,4]
>>> a
array([2, 3, 4, 2, 3, 4, 2, 3, 4, 2])
>>> a.flat = range(100)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

3
你已经准确地描述了这个特性——它只允许在对一维数组进行高级索引时与赋值结合使用。虽然我确信我在文档中读过这个内容,但我现在找不到相关链接。这在某些情况下很有用,不过我认为如果能够支持一个专门的函数,并且常规赋值仍会报错,那就更好了。 - Sven Marnach
没错,我很快就假定它只是广播,但现在我看到它实际上并不符合广播的要求!奇怪! - wim
我正在尝试其他有趣的案例,比如源数组较小的情况 a[[0,1,2]] = [-1, -2](它会循环),源数组较大的情况 a[[0,1,2]] = [-1, -2, -3, -4](它会停止),以及目标数组重复的情况 a[[0,0,1]] = [-1, -2, -3](它似乎在源数组上迭代。这会对 += 运算符造成严重影响)。 - wim
谢谢大家的建议,我认为这个功能很有用,但我同意 @SvenMarnach 的想法,我更喜欢在一个函数中实现这个功能。 - Bi Rico
@Bago,正如常见问题解答所解释的那样,[0,0,1]情况并不是NumPy的设计选择。这是Python语义强加给我们的东西。 - Robert Kern
显示剩余4条评论
1个回答

1

我认为这种行为是基于R及其祖先S/S-plus模型的。那就是列表赋值(“向量”赋值)在那里的工作方式,被称为“循环利用”。R项目网站谈到了它,但我在this link找到了更有启发性的解释。在R中,向量是一组测量值,因此按照它的方式填充或修剪它是有意义的。这种逻辑在numpy中有多少得到了应用,以及为什么,仍然是一个好问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接