将两个numpy ndarray数组与命名字段组合在一起

时间:2015-12-03 19:04:34

标签: python arrays numpy multidimensional-array

如何将两个具有命名字段且长度相同的numpy ndarray正确组合成一个ndarray?在下面的示例中,我想将xndynd合并为一个numpy ndarray。

我知道如何从xndynd的连接dtype创建新的ndarray,然后迭代地将xndynd中的内容复制到新的ndarray中。但是有一个numpy命令会为我做这个吗?

最快,最简单的xndynd合并方式非常理想。也许将ynd附加到xnd而不是制作副本?该解决方案需要使用大型ndarray快速工作。

我已经看到了几个关于如何组合简单的n维numpy数组的例子,但它们并没有帮助我解决这个问题。我示例底部带有znd = np.join((xnd, ynd))的行是我遇到的问题。

谢谢!

import numpy as np

n = 10

t = np.arange(n)
abc = np.array((t,t+n,t+2*n)).T
y = (t*10).astype(np.uint32) 


# Create x ndarray
xdt = np.dtype([
    ('t', np.float64),
    ('abc', (np.float32, 3) )
    ])
xnd = np.ndarray( shape=n, dtype=xdt)
xnd['t'] = t
xnd['abc'] = abc

# Create y ndarray
ydt = np.dtype([
    ('y', np.uint32),
    ])
ynd = np.ndarray( shape=n, dtype=ydt)
ynd['y'] = y


print xnd.dtype
# [('t', '<f8'), ('abc', '<f4', (3,))]
print ynd.dtype
# [('y', '<u4')]


# Combine x and y
# This line not correct.  What is the proper way to do this?
znd = np.join((xnd, ynd)) 

print znd.dtype
# [('t', '<f8'), ('abc', '<f4', (3,)), ('y', '<u4')]

1 个答案:

答案 0 :(得分:0)

这里是recarray函数的作用 - 按名称复制字段:

In [10]: zdt=[('t', '<f8'), ('abc', '<f4', (3,)), ('y', '<u4')]
In [11]: znd=np.zeros(xnd.shape, dtype=zdt)

In [12]: for name in xnd.dtype.names:
   ....:     znd[name]=xnd[name]
   ....:     

In [13]: for name in ynd.dtype.names:
    znd[name]=ynd[name]
   ....:     

In [14]: znd
Out[14]: 
array([(0.0, [0.0, 10.0, 20.0], 0L), (1.0, [1.0, 11.0, 21.0], 10L),
       (2.0, [2.0, 12.0, 22.0], 20L), (3.0, [3.0, 13.0, 23.0], 30L),
       (4.0, [4.0, 14.0, 24.0], 40L), (5.0, [5.0, 15.0, 25.0], 50L),
       (6.0, [6.0, 16.0, 26.0], 60L), (7.0, [7.0, 17.0, 27.0], 70L),
       (8.0, [8.0, 18.0, 28.0], 80L), (9.0, [9.0, 19.0, 29.0], 90L)], 
      dtype=[('t', '<f8'), ('abc', '<f4', (3,)), ('y', '<u4')])

由于通常记录的数量远远大于字段数,因此这种迭代并不昂贵。

可能有一些功能可以从各个联盟中创建联盟zdt,但我现在不打算挖掘它。

有一个递归执行字段复制的函数。如果dtype是嵌套的,则需要这样做 - 具有复合dtypes的字段。

您还可以从元组列表中创建一个新数组 - 每个记录一个元组。在这里,我使用zip()迭代2个数组,并使用元组连接加入它们的记录。

np.array([tuple(x)+tuple(y) for x,y in zip(xnd,ynd)],dtype=zdt)

我预计这会更慢,至少当行数多于字段时。

由于在这种情况下字段中没有重叠,因此只需连接dtypes dtye.descr即可创建新的dtype。 descr是一个列表;一个列表可以加入另一个列表。

In [26]: np.dtype(xnd.dtype.descr+ynd.dtype.descr)
Out[26]: dtype([('t', '<f8'), ('abc', '<f4', (3,)), ('y', '<u4')])