In [1019]: a=np.array([[1,2,3],[4,7,5],[9,0,1]])
In [1020]: b=a[:,(0,2)]
Это a
, который вы сортируете; структурированный массив с 3 полями. Он использует тот же буфер данных, но интерпретирует группы из 3 целых чисел как поля, а не столбцы.
In [1021]: a.view('i,i,i')
Out[1021]:
array([[(1, 2, 3)],
[(4, 7, 5)],
[(9, 0, 1)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
По той же логике вы пытаетесь view
b
:
In [1022]: b.view('i,i')
/usr/local/bin/ipython3:1: DeprecationWarning: Changing the shape of non-C contiguous array by
descriptor assignment is deprecated. To maintain
the Fortran contiguity of a multidimensional Fortran
array, use 'a.T.view(...).T' instead
#!/usr/bin/python3
....
ValueError: new type not compatible with array.
Но если я использую 3 поля вместо 2, это работает (но с тем же предупреждением):
In [1023]: b.view('i,i,i')
/usr/local/bin/ipython3:1: DeprecationWarning:...
Out[1023]:
array([[(1, 4, 9), (3, 5, 1)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
Проблема в том, что b
это Fortran order
. Проверьте b.flags
или
In [1026]: a.strides
Out[1026]: (12, 4)
In [1027]: b.strides
Out[1027]: (4, 12)
b
— это копия, а не представление. Я не знаю, навскидку, почему эта конструкция b
изменила порядок.
Прислушиваясь к предупреждению, я могу сделать:
In [1047]: b.T.view('i,i,i').T
Out[1047]:
array([[(1, 4, 9), (3, 5, 1)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
Копию по умолчанию (порядок c) b
можно рассматривать как 2 поля:
In [1042]: b1=b.copy()
In [1043]: b1.strides
Out[1043]: (8, 4)
In [1044]: b1.view('i,i')
Out[1044]:
array([[(1, 3)],
[(4, 5)],
[(9, 1)]],
dtype=[('f0', '<i4'), ('f1', '<i4')])
Сноска на: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
Структура памяти результатов расширенного индексирования оптимизируется для каждой операции индексирования, и нельзя предполагать какой-либо конкретный порядок памяти.
====================
b
в этом случае был построен с расширенной индексацией и, следовательно, является копией, даже истинное представление может быть недоступно для просмотра таким образом:
In [1052]: a[:,:2].view('i,i')
....
ValueError: new type not compatible with array.
In [1054]: a[:,:2].copy().view('i,i')
Out[1054]:
array([[(1, 2)],
[(4, 7)],
[(9, 0)]],
dtype=[('f0', '<i4'), ('f1', '<i4')])
Представление выбирает подмножество значений: "i,i,x,i,i,x,i,i,x...", и это не преобразуется в структурированный dtype.
Структурированное представление a
делает: '(i,i,i),(i,i,i),...'
Вы можете выбрать подмножество полей структурированного массива:
In [1059]: a1=a.view('i,i,i')
In [1060]: a1
Out[1060]:
array([[(1, 2, 3)],
[(4, 7, 5)],
[(9, 0, 1)]],
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])
In [1061]: b1=a1[['f0','f2']]
In [1062]: b1
Out[1062]:
array([[(1, 3)],
[(4, 5)],
[(9, 1)]],
dtype=[('f0', '<i4'), ('f2', '<i4')])
Но есть пределы того, что вы можете сделать с таким представлением. Значения можно изменить в a1
и увидеть в a
и b1
. Но я получаю сообщение об ошибке, если пытаюсь изменить значения в b1
. Это на грани развития.
person
hpaulj
schedule
29.11.2016