Посмотреть на массив numpy?

92

У меня есть 2D- numpyмассив. Есть ли способ создать на нем представление, которое включало бы первыеk строки и все столбцы?

Дело в том, чтобы избежать копирования базовых данных (массив настолько велик, что создание частичных копий невозможно).

NPE
источник

Ответы:

232

Конечно, просто проиндексируйте его как обычно. Например, y = x[:k, :] это вернет представление в исходный массив. Никакие данные не будут скопированы, а любые обновления, внесенные в, yбудут отражены xи наоборот.


Редактировать:

Я обычно работаю с 3D-массивами uint8 размером более 10 ГБ, поэтому я очень беспокоюсь об этом ... Numpy может быть очень эффективным в управлении памятью, если вы помните несколько вещей. Вот несколько советов, как избежать копирования массивов в памяти:

Используйте +=, -=, *=и т.д. , чтобы избежать создания копии массива. Например x += 10, модифицирует массив на месте, а x = x + 10сделает копию и изменит его. (также посмотрите numexpr )

Если вы действительно хотите сделать копию x = x + 10, имейте в виду, что x = x + 10.0это приведет xк автоматическому преобразованию в массив с плавающей запятой, если это еще не было. Однако, x += 10.0где x- целочисленный массив, вызовет10.0 массивом, вместо этого к преобразованию в тип int той же точности, что и у массива.

Кроме того, многие функции numpy принимают outпараметр, поэтому вы можете делать такие вещи, как np.abs(x, x)получение абсолютного значения xна месте.


В качестве второго редактирования, вот еще несколько советов по просмотрам и копиям с множественными массивами:

В отличие от списков Python, y = x[:]он не возвращает копию, а возвращает представление. Если вам нужна копия (которая, конечно, удвоит объем используемой вами памяти), используйтеy = x.copy()

Вы часто слышите о "причудливой индексации" numpy массивов. Использование списка (или целочисленного массива) в качестве индекса - это «причудливая индексация». Это может быть очень полезно, но копирует данные.

В качестве примера: y = x[[0, 1, 2], :]возвращает копию, а y = x[:3,:]возвращает представление.

Даже действительно сумасшедшая индексация, такая как x[4:100:5, :-10:-1, None]«нормальная» индексация, тем не менее, вернет представление, поэтому не бойтесь использовать всевозможные уловки нарезки для больших массивов.

x.astype(<dtype>)вернет копию данных как новый тип, а x.view(<dtype>)вернет представление.

Однако будьте осторожны ... Он чрезвычайно мощный и полезный, но вам нужно понимать, как основные данные хранятся в памяти. Если у вас есть массив чисел с плавающей запятой и вы рассматриваете их как целые числа, (или наоборот) numpy будет интерпретировать базовые биты массива как целые числа.

Например, это означает, что 1.064-битное число с плавающей запятой в системе с прямым порядком байтов будет 4607182418800017408рассматриваться как 64-битное целое число, а массив - [ 0, 0, 0, 0, 0, 0, 240, 63]как uint8. Это действительно хорошо, когда вам нужно выполнить какое-то изменение битов на больших массивах, хотя ... У вас есть низкоуровневый контроль над тем, как интерпретируется буфер памяти.

Джо Кингтон
источник
Спасибо за очень хорошие советы! Я читал руководство пользователя Numpy и не понимал, почему он был x[np.array([1, 1, 3, 1])] += 1изменен x. Теперь понял!
tnq177
хорошие советы! У меня есть еще один вопрос. Как доказать, что numpy не запускает копию, а просто просмотр? python id () кажется неспособным к этому.
wuhaochi
3
@wuhaochi Если bесть взгляд a, то b.base is aбудет True. Копия (любого массива) всегда будетarr_copy.base is None
Юрг Мерлин Спаак