2013-02-18 70 views
3

[此文章的早期版本的标题不准确“如何将一列添加到numpy记录数组?”问题在早期标题已部分answered,但这个答案不是什么机构这个帖子的早期版本所要求的。我重写了这个标题,并且对这个帖子进行了大量编辑,以使区分更加清晰。我也解释了为什么我刚才提到的答案达不到的东西我要找的。]如何堆叠numpy记录的数组?


假设我有两个numpy阵列xy,每组[R“记录”(又名“结构化“)阵列。让的x形状是(- [RÇ X)和y形状是(- [RÇý)。我们还假设x.dtype.namesy.dtype.names之间没有重叠。

例如,对于- [R = 2,Ç X = 2,并且ÇŶ = 1:

import numpy as np 
x = np.array(zip((1, 2), (3., 4.)), dtype=[('i', 'i4'), ('f', 'f4')]) 
y = np.array(zip(('a', 'b')), dtype=[('s', 'a10')]) 

我想 “水平” 串联xy产生记录数组z,形状(r,c x + c y)。此操作根本不应修改xy

一般来说,z = np.hstack((x, y))不会做,因为dtype的在xy不一定匹配。例如,继续上面的例子:

z = np.hstack((x, y)) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-7-def477e6c8bf> in <module>() 
----> 1 z = np.hstack((x, y)) 
TypeError: invalid type promotion 


现在,有一个功能,numpy.lib.recfunctions.append_fields,那看起来像它可能做一些接近我正在寻找,但我没有能够从中得到任何东西:我尝试过的所有事情要么是失败,要么是产生的东西不是我想要得到的东西。

可有人请告诉我明确在上面的例子中定义的代码(使用n.l.r.append_fields或以其他方式),这将产生,从xy,一个阵列的记录,z,相当于xy的横向级联,并且在不修改xy的情况下这样做?

我认为这只需要一行或两行代码。当然,我正在寻找不需要建筑物z的代码,通过记录来迭代xy。此外,代码可以假定xy具有相同的记录数,并且在x.dtype.namesy.dtype.names之间没有重叠。除此之外,我正在寻找的代码应该对xy一无所知。理想情况下,它也应该是不可知论的数组加入。 IOW,遗漏了错误检查,我正在寻找的代码可能是函数的主体hstack_rec,因此新阵列z将会是结果hstack_rec((x, y))


...虽然我不得不承认,在我与numpy.lib.recfunctions.append_fields失败迄今为止在完美的纪录,我已经变得有点好奇如何此功能可用于在全部,不管它与这个职位的问题的相关性。

+0

'当d = np.array([3.2],D型细胞= np.double) Z = rf.append_fields(X ,'field4',data = [d],dtypes = [np.double],usemask = False)' – 2013-10-16 18:24:10

回答

4

我从来不使用recarrays,所以别人会想出一些东西,但也许merge_arrays会工作?

>>> import numpy.lib.recfunctions as nlr 
>>> x = np.array(zip((1, 2), (3., 4.)), dtype=[('i', 'i4'), ('f', 'f4')]) 
>>> y = np.array(zip(('a', 'b')), dtype=[('s', 'a10')]) 
>>> x 
array([(1, 3.0), (2, 4.0)], 
     dtype=[('i', '<i4'), ('f', '<f4')]) 
>>> y 
array([('a',), ('b',)], 
     dtype=[('s', '|S10')]) 
>>> z = nlr.merge_arrays([x, y], flatten=True) 
>>> z 
array([(1, 3.0, 'a'), (2, 4.0, 'b')], 
     dtype=[('i', '<i4'), ('f', '<f4'), ('s', '|S10')]) 
+0

值得注意的是,尽管'recfunctions'被这样命名,merge_arrays也适用于结构化数组,阵列!一个惊喜。 – mach 2018-02-24 02:15:55

0

这是一个很晚的答案,但也许会对别人有所帮助。在用相同的标准提出同样的问题之后,我使用了这个解决方案。

它不会生成一个新的numpy数组,但通过使用zipitertools.chain它会快得多。就我而言,我需要按顺序访问每一行的每个值。下面是基准,这模拟了这种用例:

import numpy 
from numpy.lib.recfunctions import merge_arrays 
from itertools import chain 

a = numpy.empty(3, [("col1", int), ("col2", float)]) 
b = numpy.empty(3, [("col3", int), ("col4", "U1")]) 

结果:

%timeit [i for i in (row for row in merge_arrays([a,b], flatten=True))] 
52.9 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

%timeit [i for i in (row for row in (chain(i,k) for i,k in zip(a,b)))] 
3.47 µs ± 52 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)