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

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

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

Ответ 1

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


Изменить:

Я обычно работаю s > 10GB 3D-массивами uint8, поэтому я очень об этом беспокоюсь... 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>) вернет представление.

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

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