tutorial functions español python numpy

python - functions - Conversión de tipo in situ de una matriz NumPy



numpy tutorial español pdf (5)

Dado un arreglo NumPy de int32 , ¿cómo lo convierto en float32 en su lugar ? Entonces, básicamente, me gustaría hacer

a = a.astype(numpy.float32)

sin copiar la matriz. Es grande.

La razón para hacer esto es que tengo dos algoritmos para el cálculo de a . Uno de ellos devuelve una matriz de int32 , el otro devuelve una matriz de float32 (y esto es inherente a los dos algoritmos diferentes). Todos los cálculos posteriores suponen que a es una matriz de float32 .

Actualmente realizo la conversión en una función C llamada via ctypes . ¿Hay alguna manera de hacer esto en Python?


Actualización: esta función solo evita la copia si puede, por lo tanto, esta no es la respuesta correcta para esta pregunta. La respuesta de @ unutbu es la correcta.

a = a.astype(numpy.float32, copy=False)

numpy astype tiene una bandera de copia. ¿Por qué no deberíamos usarlo?


Puede cambiar el tipo de matriz sin convertirlo así:

a.dtype = numpy.float32

pero primero tienes que cambiar todos los enteros por algo que se interpretará como el flotador correspondiente. Una forma muy lenta de hacer esto sería usar el módulo struct de python así:

def toi(i): return struct.unpack(''i'',struct.pack(''f'',float(i)))[0]

... aplicado a cada miembro de tu matriz.

Pero quizás una forma más rápida sería utilizar las herramientas ctypeslib de numpy (con las que no estoy familiarizado)

- editar -

Como ctypeslib parece no funcionar, entonces procedo con la conversión con el método numpy.astype típico, pero procedo en tamaños de bloque que están dentro de los límites de su memoria:

a[0:10000] = a[0:10000].astype(''float32'').view(''int32'')

... luego cambia el tipo cuando termine.

Aquí hay una función que realiza la tarea para cualquier dtypes compatible (solo funciona para los dtypes con elementos del mismo tamaño) y maneja matrices de forma arbitraria con control del usuario sobre el tamaño del bloque:

import numpy def astype_inplace(a, dtype, blocksize=10000): oldtype = a.dtype newtype = numpy.dtype(dtype) assert oldtype.itemsize is newtype.itemsize for idx in xrange(0, a.size, blocksize): a.flat[idx:idx + blocksize] = / a.flat[idx:idx + blocksize].astype(newtype).view(oldtype) a.dtype = newtype a = numpy.random.randint(100,size=100).reshape((10,10)) print a astype_inplace(a, ''float32'') print a


Puede hacer una vista con un tipo de letra diferente y luego copiar en contexto en la vista:

import numpy as np x = np.arange(10, dtype=''int32'') y = x.view(''float32'') y[:] = x print(y)

rendimientos

array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32)

Para mostrar que la conversión estuvo en su lugar, tenga en cuenta que al copiar de x a y altera x :

print(x)

huellas dactilares

array([ 0, 1065353216, 1073741824, 1077936128, 1082130432, 1084227584, 1086324736, 1088421888, 1090519040, 1091567616])


Utilizar esta:

In [105]: a Out[105]: array([[15, 30, 88, 31, 33], [53, 38, 54, 47, 56], [67, 2, 74, 10, 16], [86, 33, 15, 51, 32], [32, 47, 76, 15, 81]], dtype=int32) In [106]: float32(a) Out[106]: array([[ 15., 30., 88., 31., 33.], [ 53., 38., 54., 47., 56.], [ 67., 2., 74., 10., 16.], [ 86., 33., 15., 51., 32.], [ 32., 47., 76., 15., 81.]], dtype=float32)


a = np.subtract(a, 0., dtype=np.float32)