Тот факт, что вы используете range
вместо списка, не имеет ничего общего с вашей ошибкой.
Создать массив с отличительными значениями:
In [30]: a = np.arange(9).reshape(3,3)
In [31]: a
Out[31]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
Индексирование с двумя диапазонами дает массив 1d, в данном случае диагональ.
In [32]: a[range(3),range(3)]
Out[32]: array([0, 4, 8])
a[[0,1,2], [0,1,2]]
сделал бы то же самое. Блок (3,) в вашей ошибке ссылается на этот 1d массив.
Чтобы получить блок, эквивалентный срезу [0:3, 0:3]
, вы должны использовать массивы, которые транслируются друг против друга. Удобная утилита - ix_
:
In [33]: np.ix_(range(3), range(3))
Out[33]:
(array([[0],
[1],
[2]]), array([[0, 1, 2]]))
Обратите внимание, что один массив (3,1), другой (1,3); передаваемые вместе, они ссылаются на (3,3) блок значений:
In [34]: a[np.ix_(range(3), range(3))]
Out[34]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
Теперь мы можем присвоить ему (3,3) массив значений:
In [35]: a[np.ix_(range(3), range(3))] = np.ones((3,3))
In [36]: a
Out[36]:
array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])