Numpy: постоянные изменения в использовании numpy.ndarray.view? - PullRequest
3 голосов
/ 19 октября 2011

Если я хочу навсегда изменить тип данных массива numpy, будет ли переназначение лучшим способом?

Вот пример, иллюстрирующий синтаксис:

import numpy as np
x = np.array([1],dtype='float')
x = x.view(dtype=('x','float"))

Однако я бы предпочел изменить тип данных «на месте».

Есть ли способ изменить dtype массива на месте?Или лучше чтобы что-то похожее на это?

1009 *

1 Ответ

5 голосов
/ 19 октября 2011

Не существует "постоянного" dtype, на самом деле.

Массивы Numpy - это просто способ просмотра буфера памяти.

Представления в буквальном смысле слова - это просто другой способ нарезки и нарезания одного и того же буфера памяти без создания копии.

Имейте в виду, однако, что это дает вам низкоуровневый контроль над тем, как интерпретируется буфер памяти.

Например:

import numpy as np
x = np.arange(10, dtype=np.int)

print 'An integer array:', x
print 'But if we view it as a float:', x.view(np.float)
print "...It's probably not what we expected..."

Это дает:

An integer array: [0 1 2 3 4 5 6 7 8 9]
But if we view it as a float: [  0.00000000e+000   4.94065646e-324   
   9.88131292e-324   1.48219694e-323   1.97626258e-323   
   2.47032823e-323   2.96439388e-323   3.45845952e-323
   3.95252517e-323   4.44659081e-323]
...It's probably not what we expected...

Итак, в данном случае мы интерпретируем базовые биты исходного буфера памяти как плавающие.

Если бы мы хотели сделать новую копию с целыми числами, преобразованными как числа с плавающей запятой, мы бы использовали x.astype(np.float).

Причина, по которой представления (из dtypes ... Slicing также возвращает представление, хотя это отдельная тема.) Настолько полезны, что вы можете делать действительно хорошие трюки, не дублируя вещи в памяти.

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

import numpy as np
x = np.arange(10, dtype=np.int)
print 'The original int array:', x

# We would have just used y = x.astype(np.float), but it makes a copy.
# This doesn't. If we're worried about memory consumption, it's handy!
y = x.view(np.float)
y[:] = x

print 'The new float array:', y
print 'But, the old int array has been modified in-place'
print x
print "They're both views into the same memory buffer!"

Аналогично, вы можете выполнять различные низкоуровневые бит-тиддлинги:

import numpy as np
x = np.arange(10, dtype=np.uint16)
y = x.view(np.uint8)

print 'The original array:', x
print '...Viewed as uint8:', y
print '...Which we can do some tricks with', y[::2]

# Now let's interpret the uint16's as two streams of uint8's...
a, b = y[::2], y[1::2]
b[:] = np.arange(10, dtype=np.uint8)
print a
print b
print x
print y
# Notice that the original is modified... We're not duplicating memory anywhere!

Чтобы ответить на ваш вопрос, «лучше» - все относительно. Вам нужна копия или вы хотите просмотреть один и тот же буфер памяти по-другому?

Как примечание, astype всегда делает копию, независимо от dtypes «input» и «output». Часто это то, что люди действительно хотят, когда они ссылаются на view. (например, если вы хотите конвертировать между типами ints и float, используйте astype, а не view, если вам не нужно микроуправлять использованием памяти.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...