Предположим, у вас есть структурированный массив 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,)]
Теперь, если я хочу изменить одну из записей на другое значение, следующие два способа кажутся эквивалентными (Случай I):
# 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
Я подумал, что, возможно, во втором случае, версия б), создается новый объект, поэтому присвоение нового значения этим записям влияет только на новый объект, но не на исходный. Но также и в первом случае, версии b), создается впечатление, что создается новый объект, так как оба следующих оператора возвращают False
:
print(a[1]['val'] is a['val'][1])
print(a['val'][[0, 1]] is a[[0, 1]]['val'])
Тот факт, что эта двусмысленность дается только в первом случае, но не во втором, кажется мне непоследовательным, если, по крайней мере, сбивает с толку. Что мне не хватает?
is
не является хорошим тестом. Важно то, производит ли первое индексированиеcopy
илиview
.a[...][...] = value
особенно чувствителен к этому различию. - person hpaulj   schedule 24.04.2020arr[[0,1]][1:] = 1
не изменитarr
.arr[[0,1]]
— расширенная индексация;arr[0]
иarr[3:]
являются базовыми, независимо от dtype. - person hpaulj   schedule 24.04.2020a['val']
,a[1]
иa[[0,1]]
. Обратите внимание на форму и тип. Индексация полей и записей не взаимозаменяемы. И индексирование полей не является индексированием столбцов. - person hpaulj   schedule 24.04.2020