Я хочу нарезать массив NumPy nxn. Я хочу извлечь произвольный выбор из m строк и столбцов этого массива (т.е. без какого-либо шаблона в количестве строк / столбцов), сделав его новым массивом mxm. Для этого примера допустим, что массив 4x4, и я хочу извлечь из него массив 2x2.
Вот наш массив:
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
Строка и столбцы для удаления совпадают. Самый простой случай, когда я хочу извлечь подматрицу 2x2, которая находится в начале или в конце, то есть:
In [33]: x[0:2,0:2]
Out[33]:
array([[0, 1],
[4, 5]])
In [34]: x[2:,2:]
Out[34]:
array([[10, 11],
[14, 15]])
Но что, если мне нужно удалить другую смесь строк / столбцов? Что если мне нужно удалить первую и третью строки / строки, извлекая таким образом подматрицу [[5,7],[13,15]]
? Может быть любая композиция строк / строк. Я где-то читал, что мне просто нужно проиндексировать мой массив, используя массивы / списки индексов для строк и столбцов, но это, похоже, не работает:
In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])
Я нашел один способ, а именно:
In [61]: x[[1,3]][:,[1,3]]
Out[61]:
array([[ 5, 7],
[13, 15]])
Первая проблема заключается в том, что она едва читаема, хотя я могу жить с этим. Если у кого-то есть лучшее решение, я, конечно, хотел бы услышать это.
Другое дело, что я читал на форуме, что индексация массивов с помощью массивов вынуждает NumPy сделать копию нужного массива, поэтому при обработке больших массивов это может стать проблемой. Почему это так / как работает этот механизм?
x[[[1],[3]],[1,3]]
создает только один новый массив, копируяx[[1,3],:][:,[1,3]]
дважды, поэтому используйте первый.Я не думаю, что
x[[1,3]][:,[1,3]]
это вряд ли читается. Если вы хотите лучше понять свои намерения, вы можете сделать:Я не эксперт в нарезке, но обычно, если вы пытаетесь нарезать массив, а значения являются непрерывными, вы получаете представление, в котором изменяется значение шага.
Например, в ваших входах 33 и 34, хотя вы получаете массив 2x2, шаг равен 4. Таким образом, когда вы индексируете следующую строку, указатель перемещается в правильную позицию в памяти.
Ясно, что этот механизм не очень хорошо подходит для массива индексов. Следовательно, NumPy должен будет сделать копию. В конце концов, многие другие математические функции матрицы зависят от размера, шага и непрерывного выделения памяти.
источник
Если вы хотите пропустить все остальные строки и все остальные столбцы, то вы можете сделать это с помощью базовой нарезки:
Это возвращает представление, а не копию вашего массива.
while
z=x[(1,3),:][:,(1,3)]
использует расширенную индексацию и, таким образом, возвращает копию:Обратите внимание, что
x
без изменений:Если вы хотите выбрать произвольные строки и столбцы, то вы не можете использовать базовую нарезку. Вам придется использовать расширенную индексацию, используя что-то вроде
x[rows,:][:,columns]
, гдеrows
иcolumns
являются последовательностями. Это, конечно, даст вам копию, а не вид вашего исходного массива. Это, как и следовало ожидать, поскольку массивный массив использует непрерывную память (с постоянными шагами), и не было бы никакого способа генерировать представление с произвольными строками и столбцами (так как это потребовало бы непостоянных шагов).источник
С помощью numpy вы можете передать срез для каждого компонента индекса, поэтому ваш
x[0:2,0:2]
приведенный выше пример работает.Если вы просто хотите равномерно пропустить столбцы или строки, вы можете передать срезы с тремя компонентами (то есть начало, остановка, шаг).
Опять же, для вашего примера выше:
Что в основном: срез в первом измерении, начиная с индекса 1, останавливается, когда индекс равен или больше 4, и добавляет 2 к индексу в каждом проходе. То же самое для второго измерения. Опять же: это работает только для постоянных шагов.
Синтаксис, который вам нужно сделать, чтобы сделать что-то совсем другое внутри - что на
x[[1,3]][:,[1,3]]
самом деле делает, это создает новый массив, включающий только строки 1 и 3 из исходного массива (сделано сx[[1,3]]
деталью), а затем повторно разрезает это - создавая третий массив - включая только столбцы 1 и 3 предыдущего массива.источник
У меня есть подобный вопрос здесь: написание в под-массиве ndarray наиболее питонским способом. Python 2 .
Следуя решению предыдущего поста для вашего случая, решение выглядит так:
Использование ix_:
Который:
источник
Я не уверен, насколько это эффективно, но вы можете использовать range () для нарезки по обеим осям
источник