У меня есть массив 2D numpy
. Есть ли способ создать представление на нем, которое будет включать в себя первые строки k
и все столбцы?
Необходимо избегать копирования базовых данных (массив настолько велик, что частичные копии невозможны).
У меня есть массив 2D numpy
. Есть ли способ создать представление на нем, которое будет включать в себя первые строки k
и все столбцы?
Необходимо избегать копирования базовых данных (массив настолько велик, что частичные копии невозможны).
Конечно, просто проиндексируйте его, как обычно. Например. 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. Это действительно приятно, когда вам нужно немного разбить бит на больших массивах, хотя... У вас есть низкий уровень контроля над тем, как интерпретируется буфер памяти.