Посмотреть на массив Numpy?
У меня есть 2D numpy
массив. Есть ли способ создать вид на него, который будет включать в себя первый k
строки и все столбцы?
Смысл в том, чтобы избежать копирования базовых данных (массив настолько велик, что создание частичных копий невозможно).
1 ответ
Конечно, просто индексируйте его, как обычно. Например y = x[:k, :]
Это вернет представление в исходный массив. Данные не будут скопированы, а любые обновления будут сделаны y
будет отражено в x
и наоборот.
Редактировать:
Я обычно работаю с>10 ГБ 3D-массивами uint8, поэтому я очень беспокоюсь об этом... Numpy может быть очень эффективным в управлении памятью, если вы помните несколько вещей. Вот несколько советов, как избегать создания копий массивов в памяти:
использование +=
, -=
, *=
и т. д., чтобы избежать копирования массива. Например x += 10
изменит массив на месте, а x = x + 10
создаст копию и изменит ее. (также посмотрите на Numberxpr)
Если вы хотите сделать копию с 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.0
как 64-разрядное число с плавающей точкой в системе с прямым порядком байтов будет 4607182418800017408
при просмотре как 64-битный int и массив [ 0, 0, 0, 0, 0, 0, 240, 63]
если рассматривать как uint8. Это действительно хорошо, когда вам нужно что-то вроде больших битов на больших массивах, хотя... У вас низкий контроль над тем, как интерпретируется буфер памяти.