Просмотр массива numpy?

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

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


person NPE    schedule 06.12.2010    source источник


Ответы (1)


Конечно, просто проиндексируйте его, как обычно. Например. 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 на месте.


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

В отличие от списков 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.0 в качестве 64-битного числа с плавающей запятой в системе с прямым порядком байтов будет 4607182418800017408 при просмотре как 64-битное целое и массив [ 0, 0, 0, 0, 0, 0, 240, 63] при просмотре как uint8. Это действительно удобно, когда вам нужно что-то изменить в больших массивах, хотя... У вас есть низкоуровневый контроль над тем, как интерпретируется буфер памяти.

person Joe Kington    schedule 06.12.2010
comment
Спасибо за очень хорошие советы! Я читал руководство пользователя Numpy и не понимал, почему x[np.array([1, 1, 3, 1])] += 1 изменил x. Теперь понял! - person tnq177; 11.07.2015
comment
хорошие советы! У меня есть еще один вопрос. Как доказать, что numpy не запускает копию, а просто просмотр? id() в python кажется неспособным на это. - person wuhaochi; 10.03.2017
comment
@wuhaochi Если b — это представление a, то b.base is a будет True. Копия (любого массива) всегда будет иметь arr_copy.base is None - person Jürg Merlin Spaak; 07.08.2017
comment
Я очень ценю советы — я работал с numpy несколько лет, но почему-то некоторые из них были мне совершенно неизвестны! - person corvus; 16.02.2021