У меня есть массив 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. Это действительно приятно, когда вам нужно немного разбить бит на больших массивах, хотя... У вас есть низкий уровень контроля над тем, как интерпретируется буфер памяти.