Учитывая массив NumPy int32
, как мне преобразовать его на float32
место ? В общем, я хотел бы сделать
a = a.astype(numpy.float32)
без копирования массива. Оно большое.
Причина этого в том, что у меня есть два алгоритма вычисления a
. Один из них возвращает массив int32
, другой - массив float32
(и это присуще двум различным алгоритмам). Все дальнейшие вычисления предполагают, что a
это массив float32
.
В настоящее время я выполняю преобразование в функции C, вызываемой через ctypes
. Есть ли способ сделать это в Python?
ctypes
- это столько же «в Python», сколько и использованиеnumpy
. :)Ответы:
Вы можете создать представление с другим типом dtype, а затем скопировать его на место в представление:
доходность
Чтобы показать, что преобразование было на месте, обратите внимание, что копирование из
x
вy
измененоx
:печать
источник
np.arange(10, dtype=np.int32).view(np.float32)
на Numpy 1.8.2, я получаюarray([ 0.00000000e+00, 1.40129846e-45, ... [snip] ... 1.26116862e-44], dtype=float32)
.y[:] = x
.a = np.arange(10, dtype='float32'); b = a[::-1]; c = np.vstack((a,b)); d = c.view('float64')
этот код принимает 10 + 10 float32 и приводит к 10, а не к 20 float64x.astype(float)
преобразование. Я бы не рекомендовал это, если ваш скрипт не граничит с MemoryError.Обновление: эта функция избегает копирования только в том случае, если это возможно, поэтому это неправильный ответ на этот вопрос. ответ unutbu правильный.
numpy astype имеет флаг копирования. Почему бы нам не использовать это?
источник
Вы можете изменить тип массива без преобразования следующим образом:
но сначала вы должны изменить все целые числа на то, что будет интерпретироваться как соответствующее число с плавающей запятой. Очень медленный способ сделать это - использовать
struct
модуль python следующим образом:... применяется к каждому члену вашего массива.
Но, возможно, более быстрым способом было бы использовать инструменты numpy ctypeslib (с которыми я не знаком)
- редактировать -
Поскольку ctypeslib, похоже, не работает, я бы продолжил преобразование обычным
numpy.astype
методом, но с размерами блоков, которые находятся в пределах вашей памяти:... затем измените dtype, когда закончите.
Вот функция, которая выполняет задачу для любых совместимых dtypes (работает только для dtypes с элементами одинакового размера) и обрабатывает массивы произвольной формы с контролем пользователя над размером блока:
источник
a.view(numpy.float32)
. Самая сложная часть - это преобразование данных.numpy.ctypeslib
помогает только переосмыслить данные, но не преобразовать их.используйте view () и параметр dtype, чтобы изменить массив на месте.
источник
int
этот ответ только переинтерпретирует существующие данные как другой тип, чего я не просил.dtype
,order
иsubok
требование вернуть копию массива? Я не решаю это.Использовать это:
источник
a = np.subtract(a, 0., dtype=np.float32)
источник
numpy.subtract
возвращает копию, не так ли? Только имяa
повторно используется для другого блока данных ... Пожалуйста, объясните, если я ошибаюсь.