Индексированное назначение может скрыть некоторые детали, которые, я думаю, более понятны с эквивалентом getitem
.
In [88]: arr = np.arange(25).reshape(5,5)
In [89]: arr
Out[89]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])
In [90]: coord = [[2,3],[1,2]]
In [91]: arr[coord]
FutureWarning: Using a non-tuple sequence for multidimensional indexing
is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the
future this will be interpreted as an array index, `arr[np.array(seq)]`,
which will result either in an error or a different result.
Out[91]: array([11, 17])
Правильное индексирование для пары точек с применением [2,3] для 1-й оси, [1,2] до 2:
In [92]: coord = ([2,3],[1,2])
In [93]: arr[coord]
Out[93]: array([11, 17])
In [94]: arr[[2,3], [1,2]]
Out[94]: array([11, 17])
Исторически numpy
был немного небрежным и интерпретировал список списков как кортеж списков (при определенных обстоятельствах).Более новые версии пытаются устранить это несоответствие.
In [95]: coord = [[2,3]]
In [96]: arr[coord]
FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
Out[96]:
array([[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
In [97]: coord = ([2,3],) # clearer - pick 2 rows, e.g. arr[[2,3],:]
In [98]: arr[coord]
Out[98]:
array([[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
In [99]: arr[2,3] # pick one point
Out[99]: 13
In [100]: coord = (2,3)
In [101]: arr[coord]
Out[101]: 13
В массиве нет этих запутанных списков для кортежей:
In [102]: coord = np.array([[2,3], [1,2]])
In [103]: arr[coord]
Out[103]:
array([[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]],
[[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]])
Это выбирает блок (2,2) изстрок.Ваш arr[coord]=30
скрыл этот шаблон, так как в выборе строк были дубликаты (и назначение буферизовано).(для небуферизованного присваивания проверьте np.add.at(t,coord,30)
).
Если мы явно сообщим ему, что coord
применяется к 1-му измерению, мы используем тот же стиль индексации массива:
In [111]: coord = [[2,3],[1,2]]
In [112]: arr[coord,:]
Out[112]:
array([[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]],
[[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]])
Примечаниеразница в форме, если я использую этот последний [coord,]
со списком из 1 элемента:
In [117]: coord = [[2,3]]
In [118]: arr[coord,]
Out[118]:
array([[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]]])
In [119]: _.shape
Out[119]: (1, 2, 5)
Поэтому сделайте coord
кортежем, а не списком, если вы хотите, чтобы каждый элемент применялся к другому измерению,Или используйте массив, если вы хотите, чтобы он применялся только к одному измерению, или используйте явное обозначение [coord,:]
.
Если вы возьмете этот массив, транспонируйте его и разбейте его на кортеж,Вы получаете индексные массивы для двух измерений:
In [120]: coord = np.array([[2,3],[1,2]])
In [121]: coord
Out[121]:
array([[2, 3],
[1, 2]])
In [123]: tuple(coord.T)
Out[123]: (array([2, 1]), array([3, 2]))
In [124]: arr[tuple(coord.T)]
Out[124]: array([13, 7])
и с 4 точками:
In [125]: coord = np.array([[2,3],[1,2],[0,0],[3,4]])
In [126]: arr[tuple(coord.T)]
Out[126]: array([13, 7, 0, 19])
Я не знаю, поможет это или нет, но np.where
часто используется для выбора точек в массиве:
Условие - кратно 4:
In [135]: arr%4==0
Out[135]:
array([[ True, False, False, False, True],
[False, False, False, True, False],
[False, False, True, False, False],
[False, True, False, False, False],
[ True, False, False, False, True]])
Индексы этих точек - кортеж с массивом для каждого измерения.Это можно использовать непосредственно в качестве индекса:
In [136]: np.where(arr%4==0)
Out[136]: (array([0, 0, 1, 2, 3, 4, 4]), array([0, 4, 3, 2, 1, 0, 4]))
In [137]: arr[_]
Out[137]: array([ 0, 4, 8, 12, 16, 20, 24])
argwhere
применяет np.transpose
к этому кортежу, создавая (n, 2) массив:
In [138]: np.argwhere(arr%4==0)
Out[138]:
array([[0, 0],
[0, 4],
[1, 3],
[2, 2],
[3, 1],
[4, 0],
[4, 4]])
Этокоординаты отдельных элементов, но их нельзя использовать непосредственно в качестве индексов, кроме как итеративно:
In [144]: [arr[i,j] for i,j in np.argwhere(arr%4==0)]
Out[144]: [0, 4, 8, 12, 16, 20, 24]
Я думаю, что вы генерируете координаты в этом стиле argwhere
, но они вам действительно нужны в where
стиль - как кортеж массивов.