如何将两个具有命名字段且长度相同的numpy ndarray正确组合成一个ndarray?在下面的示例中,我想将xnd
和ynd
合并为一个numpy ndarray。
我知道如何从xnd
和ynd
的连接dtype创建新的ndarray,然后迭代地将xnd
和ynd
中的内容复制到新的ndarray中。但是有一个numpy命令会为我做这个吗?
最快,最简单的xnd
和ynd
合并方式非常理想。也许将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')]
答案 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')])