numpy结构化数组中索引和切片的不同行为

Suppose you have a structured array a:

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6], dtype=[('val', 'i4')])
print(a)
[(1,) (2,) (3,) (4,) (5,) (6,)]

现在,如果我想将其中一项更改为其他值,则以下两种方法似乎是等效的(案例1):

# both of these work
"""version a)"""
a['val'][1] = 10
print(a)
[( 1,) (10,) ( 3,) ( 4,) ( 5,) ( 6,)]

"""version b)"""
a[1]['val'] = 2
print(a)
[(1,) (2,) (3,) (4,) (5,) (6,)]

但是,如果我们尝试更改多个条目(案例II),则这种含糊不清(不确定这是否是合适的术语)就会打破:

"""version a)"""
a['val'][[0, 1]] = 15
print(a)
[(15,) (15,) ( 3,) ( 4,) ( 5,) ( 6,)]
# this works

"""version b)"""
a[[0, 1]]['val'] = 5
print(a)
[(15,) (15,) ( 3,) ( 4,) ( 5,) ( 6,)]
# this has no effect

I thought maybe in second case, version b), a new object is created so assigning a new value to those entries only affects the new object but not the original one. But also in the first case, version b), a new object seems to be created, as both of the following statements return False:

print(a[1]['val'] is a['val'][1])
print(a['val'][[0, 1]] is a[[0, 1]]['val'])

这种模糊性仅在第一种情况下才给出,而在第二种情况下没有,这一事实至少在我看来是混乱的。我想念什么?

评论
  • eet
    eet 回复

    Great observation. Per numpy doc: For all cases of index arrays, what is returned is a copy of the original data, not a view as one gets for slices. While single element indexing returns a view.

    还要注意,根据scipy doc,调用结构化数组上的字段会创建一个视图,并且使用整数索引还会创建一个结构化标量,与其他numpy标量不同,结构化标量是可变的,并且就像原始数组中的视图一样,因此修改标量将修改原始数组。结构化标量还支持按字段名称进行访问和分配

    尽管它可能不共享内存(我不确定它的内部实现),但它的作用类似于视图并更改了原始数组。因此,当您使用单个整数调用数组时,它的作用类似于视图并更改原始数组,而当您使用整数索引的数组调用它时,它将创建一个副本,并且不会更改原始数组。