如何将2d numpy数组与结构化数组合并

时间:2015-11-12 16:23:47

标签: python numpy

我想知道如何将2d numpy数组(n行m列)与现有结构化数组(n行)合并。此示例代码显示了我要执行的操作:

//include("bar.js");

我想要的结果是

D = np.array([('a', 12), ('b', 14), ('c', 10)], dtype=np.dtype([('label','a2'),  ('ht', 'i2')]))

xxx =  np.array([[1,2,3],[5,6,7],[78,88,98]])

E = np.lib.recfunctions.merge_arrays([D, xxx])
print E

我首先尝试将xxx转换为结构化数组,并且还尝试了指定了dtype的append_fields,但在这两种方法中都没有运气。

2 个答案:

答案 0 :(得分:1)

我无法找到np.lib.recfunctions.merge_arrays。也许我们有不同的numpy版本。我不是去挖掘它,而是使用我在其他rec函数中看到的方法自己进行合并。

您的样品:

In [2]: D = np.array([('a', 12), ('b', 14), ('c', 10)],
    dtype=np.dtype([('label','a2'),  ('ht', 'i2')]))    
In [3]: xxx =  np.array([[1,2,3],[5,6,7],[78,88,98]])

In [6]: D.dtype
Out[6]: dtype([('label', 'S2'), ('ht', '<i2')])

E定义新的dtype。这可以从D.dtype构建,但我只需输入它。

In [9]: dt=np.dtype([('label', 'S2'), ('ht', '<i2'),
            ('xxx', xxx.dtype,xxx.shape[1])])

一个正确形状和dtype的新空白数组:

In [11]: E=np.zeros(D.shape, dtype=dt)

In [12]: E
Out[12]: 
array([('', 0, [0, 0, 0]), ('', 0, [0, 0, 0]), ('', 0, [0, 0, 0])], 
      dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4', (3,))])

现在从Dxxx复制字段。这种在rec函数中很常见。复合dtypes没有更精简的任何内容。

In [13]: for name in D.dtype.names:
   ....:     E[name] = D[name]    
In [14]: E['xxx']=xxx

In [15]: E
Out[15]: 
array([('a', 12, [1, 2, 3]), ('b', 14, [5, 6, 7]), ('c', 10, [78, 88, 98])], 
      dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4', (3,))])

那是你的目标,对吧?

出于某种原因,我必须单独导入recfunctions。这对numpy来说并不常见。

from numpy.lib import recfunctions

在提到merge_arraysappend_field时,你真的应该描述一下什么不起作用,是否是错误,或者你不喜欢结果。

merge_array确实有效:

In [35]: e=recfunctions.merge_arrays((D,xxx))
Out[35]: 
array([(('a', 12), 1), (('b', 14), 2), (('c', 10), 3), (('-1', -1), 5),
       (('-1', -1), 6), (('-1', -1), 7), (('-1', -1), 78),
       (('-1', -1), 88), (('-1', -1), 98)], 
      dtype=[('f0', [('label', 'S2'), ('ht', '<i2')]), ('f1', '<i4')])

只是2个输入数组是单独的字段:

In [38]: e['f0']
Out[38]: 
array([('a', 12), ('b', 14), ('c', 10), ('-1', -1), ('-1', -1), ('-1', -1),('-1', -1), ('-1', -1), ('-1', -1)], 
      dtype=[('label', 'S2'), ('ht', '<i2')])

In [39]: e['f1']
Out[39]: array([ 1,  2,  3,  5,  6,  7, 78, 88, 98])

append_fields适用于简单添加,但不适用于包含3列的xxx

In [57]: recfunctions.append_fields(D,'xxx',[1,2,3],usemask=False)
Out[57]: 
array([('a', 12, 1), ('b', 14, 2), ('c', 10, 3)], 
      dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', '<i4')])

或者我可以将xxx转换为结构化数组,并附加:

In [60]: x1=np.zeros((3,),dtype=[('xxx',int,(3,))])
In [61]: x1['xxx']=xxx
In [62]: x1
Out[62]: 
array([([1, 2, 3],), ([5, 6, 7],), ([78, 88, 98],)], 
      dtype=[('xxx', '<i4', (3,))])

In [63]: recfunctions.append_fields(D,'xxx',x1,usemask=False)
Out[63]: 
array([('a', 12, ([1, 2, 3],)), ('b', 14, ([5, 6, 7],)),
       ('c', 10, ([78, 88, 98],))], 
      dtype=[('label', 'S2'), ('ht', '<i2'), ('xxx', [('xxx', '<i4', (3,))])])

更近,但不是很正确。我可以继续玩这些功能,但值得吗?

这些是等效的,但recursive_fill处理更复杂的dtypes:

recfunctions.recursive_fill_fields(D,E)
for name in D.dtype.names: E[name] = D[name]

这是一种使用功能构建E.dtype的方法,但必须更简单:

dt2=list(recfunctions.flatten_descr(np.dtype(recfunctions.zip_descr([D,x1]))))

答案 1 :(得分:0)

[(d,list(x)) for x,d in zip(xxx,D)]

给出

[(('a', 12), [1, 2, 3]), (('b', 14), [5, 6, 7]), (('c', 10), [78, 88, 98])]

np.array([(d,list(x)) for x,d in zip(xxx,D)])

给出

array([[('a', 12), [1, 2, 3]],
       [('b', 14), [5, 6, 7]],
       [('c', 10), [78, 88, 98]]], dtype=object)