Мультиполевое индексирование находится в состоянии постоянного изменения. С 1.16
они, похоже, установили эту «смещенную» форму «представлений», требуя явной перепаковки, если вы хотите «чистую» копию.
In [231]: np.__version__
Out[231]: '1.16.1'
In [232]: a.dtype
Out[232]: dtype([('A', '<i8'), ('B', '<i8'), ('C', '<f8')])
In [233]: a[['A','C']].dtype
Out[233]: dtype({'names':['A','C'], 'formats':['<i8','<f8'], 'offsets':[0,16], 'itemsize':24})
В этом представлении значения для «B» все еще присутствуют (со смещением 8). Думайте о буфере данных как о:
[a0, b0, c0, a1, b1, c1, a2, b2, c2, ....]
[233] 'view' смотрит на тот же буфер данных, но только дает нам доступ к полям A
и C
. repack_fields
создает новый буфер данных с:
[a0, c0, a1, c1, ....]
Если бы a
был обычным (n,3)
массивом, a[:, [0,2]]
была бы копией. Мы не могли пропустить a[:,1]
и все еще иметь представление.
In [234]: np.concatenate((a[['A','C']],a[['A','C']]))
Out[234]:
array([(0, 0.), (1, 1.), (2, 2.), (0, 0.), (1, 1.), (2, 2.)],
dtype={'names':['A','C'], 'formats':['<i8','<f8'], 'offsets':[0,16], 'itemsize':24})
Играя с view
Я обнаружил, что поле со смещением 8 (поле 'B' в a
) все еще существует, но неинициализировано (как в массиве np.empty
).
Различные способы отображения этого «разбросанного» dtype:
In [238]: a1.dtype
Out[238]: dtype({'names':['A','C'], 'formats':['<i8','<f8'], 'offsets':[0,16], 'itemsize':24})
In [239]: a1.dtype.descr
Out[239]: [('A', '<i8'), ('', '|V8'), ('C', '<f8')]
In [241]: a1.dtype.fields
Out[241]: mappingproxy({'A': (dtype('int64'), 0), 'C': (dtype('float64'), 16)})
Я также могу изменить порядок полей:
In [248]: a[['B','C','A']].dtype
Out[248]: dtype({'names':['B','C','A'], 'formats':['<i8','<f8','<i8'], 'offsets':[8,16,0], 'itemsize':24})
In [249]: a[['B','C','A']].dtype.descr
...
ValueError: dtype.descr is not defined for types with overlapping or out-of-order fields