In [44]: data = np.arange(40).reshape(10,4)
Делая первую индексную (4,1) форму, мы можем индексировать с различными размерами вторых массивов:
In [46]: data[np.arange(4)[:,None],[2]]
Out[46]:
array([[ 2],
[ 6],
[10],
[14]])
In [47]: data[np.arange(4)[:,None],[1,2]]
Out[47]:
array([[ 1, 2],
[ 5, 6],
[ 9, 10],
[13, 14]])
Первый результат (4,1), второй (4,2).
С squeeze
мы получаем (4,), эквивалентный индексации:
In [48]: data[np.arange(4),2]
Out[48]: array([ 2, 6, 10, 14])
np.ix_
генерирует аналогичные наборы индексов, например, (4,1) и (1,2)
In [49]: np.ix_(np.arange(4),[1,2])
Out[49]:
(array([[0],
[1],
[2],
[3]]), array([[1, 2]]))
и (4,1) с (1,1):
In [50]: np.ix_(np.arange(4),[2])
Out[50]:
(array([[0],
[1],
[2],
[3]]), array([[2]]))
(m, 1) передает с (1, n), чтобы получить (m, n) результат. (n,) работает так же, как (1, n) - опять же правила вещания.
С изменением вы хотите присвоить значение этому (m, n) блоку. В этом случае работает (4,2), как и (4,1). Но вы хотели бы назначить (4,). Но путем трансляции (4,) можно транслировать на (1,4), а не на (4,1). Можно добавить начальное измерение, но не конечное.
In [51]: data[np.arange(4)[:,None],[2]]=np.ones(4)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-51-9245de6331ce> in <module>
----> 1 data[np.arange(4)[:,None],[2]]=np.ones(4)
ValueError: shape mismatch: value array of shape (4,) could not be
broadcast to indexing result of shape (4,1)
In [52]: data[np.arange(4)[:,None],[2]] = np.ones((4,1)) # (4,1) into (4,1)
# (4,1) also goes into a (4,2)
In [53]: data[np.arange(4),[2]] = np.ones(4) # (4,) into (4,)
In [55]: data[np.arange(4)[:,None],[1,2]] = np.zeros(2) # (2,) into (4,2)
flat
может использоваться для присвоения значений 1d способом, но здесь это не работает, потому что data[np.arange(4)[:,None],[1,2]]
является копией, если она используется каким-либо образом, кроме как непосредственно в случае __setitem__
, data[...] = ...
.