Numpy matriz estructurada agregando registro

Tengo una matriz estructurada como esta:

a = np.array([(0. , 1. , 2.) , (10. , 11. , 12. )] , dtype=[('PositionX', '<f8'), ('PositionY', '<f8'), ('PositionZ', '<f8')]) 

Ahora, quiero agregar el registro 0 (a [0]) y el registro 1 (a [1]), para obtener algo como: (10., 12., 14.)

Cuando escribo algo como:

 a[0] + a[1] 

Recibí un error que me dice que no puedes agregar dos objetos dtype o algo así.

Por lo tanto, creo que tal vez pueda convertir un [0] para ser un vector regular, y luego realizar una sum.

Pero numpy.array (a [0]) tiene el mismo dtype que a [0], y numpy.array(a[0],dtype=np.float64) tampoco funciona.

Entonces, ¿alguien puede decirme cómo convertir un [0] a un vector regular? por favor, no me digas que convierta una matriz estructurada en una matriz normal. porque solo quiero tomar un poco de mi registro de matriz y añadir. Además, realmente quiero saber cómo convertir un objeto como un [0] en un vector regular.

Recibes un error solo porque las a [i] son ​​tuplas, no puedes agregarlas directamente. Tienes que acceder a ellos, una forma más pirónica de lograrlo sería:

 map(sum, zip(*a)) 

La función zip hace exactamente lo que está buscando. Después de eso, debe procesar cada entrada de acuerdo con lo que necesita. En la sum su caso, también puede probar esto:

 result = [] for elem in zip(*a): result.append(sum(elem)) 
 In [206]: a Out[206]: array([( 0., 1., 2.), ( 10., 11., 12.)], dtype=[('PositionX', ' 

Un registro es un objeto dtype de número compuesto, que se muestra como una tupla.

 In [207]: type(a[0]) Out[207]: numpy.void In [208]: a[0].dtype Out[208]: dtype([('PositionX', ' 

Los campos ('columnas') de la matriz son matrices, y hacen la matriz matemática normal.

 In [209]: a['PositionX'] Out[209]: array([ 0., 10.]) In [210]: a['PositionX']+a['PositionY'] Out[210]: array([ 1., 21.]) 

Pero las matemáticas no se han definido para el tipo de compuesto:

 In [211]: a[0]+a[1] TypeError: ufunc 'add' did not contain a loop with signature matching types dtype([('PositionX', ' 

Si me permite convertir toda la matriz a 2d, puedo agregar filas:

 In [213]: a1=np.array(a.tolist()) In [214]: a1 Out[214]: array([[ 0., 1., 2.], [ 10., 11., 12.]]) In [215]: a1[0]+a1[1] Out[215]: array([ 10., 12., 14.]) 

Hay otras formas de convertir una matriz estructurada a 2d (con view o astype ), pero este tolist() es más fácil de usar y más consistente. Más sobre esto en https://stackoverflow.com/a/43380941/901925

Pero para hacer matemáticas con registros individuales, debe convertirlos en matrices o tratarlos como las tuplas mostradas.

 In [218]: np.array(a[0].tolist()) Out[218]: array([ 0., 1., 2.]) In [219]: np.array(a[0].tolist())+np.array(a[1].tolist()) Out[219]: array([ 10., 12., 14.]) 

Pero, ¿estás contento con esta matriz, o quieres que vuelva al tipo a.dtype ?

 In [234]: np.array(tuple(asum), a.dtype) Out[234]: array(( 10., 12., 14.), dtype=[('PositionX', ' 

Los datos de una matriz estructurada deben estar en tuplas o en una lista de tuplas.

Tienes que hacer la misma conversión de dtype si usas el enfoque con cremallera que mostró @Mohamed Lakhal

 In [236]: [i+j for i,j in zip(a[0],a[1])] Out[236]: [10.0, 12.0, 14.0] In [237]: np.array(tuple([i+j for i,j in zip(a[0],a[1])]), a.dtype) 

Mientras que un enfoque de view como comentó Divakar convierte la matriz completa:

 In [227]: a.view(' 

no funciona con un registro:

 In [229]: a[0].view(' 

Este es un convertidor mejor para la matriz 2d:

 In [239]: a.view('3f8') Out[239]: array([[ 0., 1., 2.], [ 10., 11., 12.]]) In [240]: a[0].view('3f8') Out[240]: array([ 0., 1., 2.]) In [241]: a[[0,1]].view('3f8') Out[241]: array([[ 0., 1., 2.], [ 10., 11., 12.]]) In [242]: a[[0,1]].view('3f8').sum(axis=0) Out[242]: array([ 10., 12., 14.])