Convertir una matriz estructurada con varios tipos de datos numéricos en una matriz regular

Supongamos que tengo una matriz NumPy estructurada con varios tipos de datos numéricos. Como ejemplo básico,

my_data = np.array( [(17, 182.1), (19, 175.6)], dtype='i2,f4') 

¿Cómo puedo convertir esto en una matriz de flotadores NumPy regular?

De esta respuesta , sé que podría usar

 np.array(my_data.tolist()) 

pero aparentemente es lento ya que “convierte una matriz NumPy empaquetada de manera eficiente a una lista de Python regular”.

Puedes hacerlo fácilmente con Pandas:

 >>> import pandas as pd >>> pd.DataFrame(my_data).values array([[ 17. , 182.1000061], [ 19. , 175.6000061]], dtype=float32) 

Aquí hay una forma (asumiendo que my_data es una matriz estructurada unidimensional):

 In [26]: my_data Out[26]: array([(17, 182.10000610351562), (19, 175.60000610351562)], dtype=[('f0', ' 

La forma obvia funciona:

 >>> my_data array([(17, 182.10000610351562), (19, 175.60000610351562)], dtype=[('f0', '>> n = len(my_data.dtype.names) # n == 2 >>> my_data.astype(','.join(['f4']*n)) array([(17.0, 182.10000610351562), (19.0, 175.60000610351562)], dtype=[('f0', '>> my_data.astype(','.join(['f4']*n)).view('f4') array([ 17. , 182.1000061, 19. , 175.6000061], dtype=float32) >>> my_data.astype(','.join(['f4']*n)).view('f4').reshape(-1, n) array([[ 17. , 182.1000061], [ 19. , 175.6000061]], dtype=float32) 

Una variación en la respuesta de Warren (que copia los datos por campo):

 x = np.empty((my_data.shape[0],len(my_data.dtype)),dtype='f4') for i,n in enumerate(my_data.dtype.names): x[:,i]=my_data[n] 

O podrías iterar por fila. r es una tupla. Tiene que ser convertido a una lista para llenar una fila de x . Con muchas filas y pocos campos esto será más lento.

 for i,r in enumerate(my_data): x[i,:]=list(r) 

Puede ser instructivo probar x.data=r.data y obtener un error: AttributeError: not enough data for array . x datos x son un buffer con 4 flotantes. my_data es un búfer con 2 tuplas, cada una de las cuales contiene un int y un float (o secuencia de [int float int float]). my_data.itemsize==6 . De una forma u otra, my_data se debe convertir a todos los flotadores y se debe eliminar la agrupación de tuplas.

Pero usar astype como lo demuestra Jaime funciona:

 x.data=my_data.astype('f4,f4').data 

En las pruebas rápidas que utilizan una matriz de 1000 elementos con 5 campos, copiar campo por campo es tan rápido como usar astype .