2017-04-13 68 views
0

我有一个结构数组是这样的:numpy的结构化阵列添加记录

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

现在,我想补充记录0([0]),并记录图1(a [1]),要达到这样的: (10,12,14)

当我写的东西,如:

a[0] + a[1] 

我有错误,告诉我,你不能添加两个D型物体或类似的东西。

所以,我想也许我可以把一个[0]变成一个常规矢量,然后执行添加。

但numpy.array(a [0])具有与[0]相同的dtype,并且numpy.array(a[0],dtype=np.float64)也不起作用。

那么,谁能告诉我如何将[0]转换为常规矢量?请不要告诉我隐藏结构化数组到常规数组。因为我只想取少数阵列记录并添加。 此外,我真的想知道如何将一个像[0]这样的对象转换为常规矢量。

+1

你尝试从这个职位的建议 - http://stackoverflow.com/questions/5957380/convert-structured-array-正常的numpy数组?基本上:'a.view(np.float64).reshape(len(a), - 1).sum(0)'。 – Divakar

回答

1

因为a [i]是元组,所以不能直接添加元组。您有权访问他们,更Python的方式来实现,这将是:

map(sum, zip(*a)) 

zip函数做的正是你要寻找的,在这之后,你必须根据你的需要来处理每个条目,在你的情况sum,你也可以试试这个:

result = [] 
for elem in zip(*a): 
    result.append(sum(elem)) 
+0

好吧,你的意思是拿每个元组,并在python中创建一个列表,好吧,我可以做到这一点。但我们可以用numpy完成这个吗?剂量numpy有一些方法可以将dtype转换为类似[0]的类型到正常的1d数组? –

+0

如果您试图将元组转换为列表,那么函数list就是您要查找的内容。 –

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

记录是一个复合numpy的D类对象,即显示为一个元组。

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

字段阵列的(“列”)是数组,然后执行正常阵列数学。

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

但是,数学尚未为复合D型定义:

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

如果你让我转换整个数组到2d,我可以添加行:

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.]) 

有是将结构化数组转换为2d的其他方式(使用viewastype),但此tolist()最易于使用且最一致。更多信息请登录https://stackoverflow.com/a/43380941/901925

但是要对单个记录进行数学运算,您必须将它们转换为数组或像显示的元组一样对待它们。

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.]) 

但是你对这个数组感到满意吗,还是你想要回到a.dtype

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

数据结构化数组必须在元组或元组列表中。

你,如果你使用压缩的办法,@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) 

虽然view方法,因为Divakar评论整个数组转换做同样的dtype转换:

In [227]: a.view('<f8') 
Out[227]: array([ 0., 1., 2., 10., 11., 12.]) 
In [228]: a.view('<f8').reshape(-1,3) 
Out[228]: 
array([[ 0., 1., 2.], 
     [ 10., 11., 12.]]) 

它不起作用:

In [229]: a[0].view('<f8') 
.... 
ValueError: new type not compatible with array. 

这是一个更好的转换器,二维数组:

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.])