python:numpy:命名数组的串联

标签 python numpy

考虑以下简单示例:

x = numpy.array([(1,2),(3,4)],dtype=[('a','<f4'),('b','<f4')])
y = numpy.array([(1,2),(3,4)],dtype=[('c','<f4'),('d','<f4')])
numpy.hstack((x,y))

将出现以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python33\lib\site-packages\numpy\core\shape_base.py", line 226, in vstack
    return _nx.concatenate(list(map(atleast_2d,tup)),0)
TypeError: invalid type promotion

如果数组没有标题它可以工作

x = numpy.array([(1,2),(3,4)],dtype='<f4')
y = numpy.array([(1,2),(3,4)],dtype='<f4')
numpy.hstack((x,y))

如果我从 x 和 y 中删除名称,它也可以工作。

问题:如何连接标题为numpy的数组的vstack或hstack? 注意:numpy.lib.recfunctions.stack_arrays 也不能正常工作

最佳答案

问题是类型不一样。 “标题”是类型的一部分,y 使用与 x 不同的名称,因此类型不兼容。如果您使用兼容类型,一切正常:

>>> x = numpy.array([(1, 2), (3, 4)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> y = numpy.array([(5, 6), (7, 8)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.vstack((x, y))
array([[(1.0, 2.0), (3.0, 4.0)],
       [(5.0, 6.0), (7.0, 8.0)]], 
      dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.hstack((x, y))
array([(1.0, 2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)], 
      dtype=[('a', '<f4'), ('b', '<f4')])
>>> numpy.dstack((x, y))
array([[[(1.0, 2.0), (5.0, 6.0)],
        [(3.0, 4.0), (7.0, 8.0)]]], 
      dtype=[('a', '<f4'), ('b', '<f4')])

有时 dstack 等足够聪明以合理的方式强制类型,但 numpy 无法知道如何将记录数组与不同的用户定义组合字段名称。

如果您想连接数据类型,那么您必须创建一个新的数据类型。不要错误地认为名称序列 (x['a'], x['b']...) 构成了真正的维度数组; xy 是内存块的一维数组,每个包含两个 32 位 float ,可以使用名称 'a''b'。但是正如您所看到的,如果您访问数组中的单个项目,则不会像真正的第二维那样获得另一个数组。你可以在这里看到区别:

>>> x = numpy.array([(1, 2), (3, 4)], dtype=[('a', '<f4'), ('b', '<f4')])
>>> x[0]
(1.0, 2.0)
>>> type(x[0])
<type 'numpy.void'>

>>> z = numpy.array([(1, 2), (3, 4)])
>>> z[0]
array([1, 2])
>>> type(z[0])
<type 'numpy.ndarray'>

这就是允许记录数组包含异构数据的原因;记录数组可以同时包含字符串和整数,但代价是您无法在单个记录级别获得 ndarray 的全部功能。

结果是,要连接各个内存块,您实际上必须修改数组的 dtype。有几种方法可以做到这一点,但我能找到的最简单的方法涉及鲜为人知的 numpy.lib.recfunctions 库(我看你已经找到了!):

>>> numpy.lib.recfunctions.rec_append_fields(x, 
                                             y.dtype.names, 
                                             [y[n] for n in y.dtype.names])
rec.array([(1.0, 2.0, 1.0, 2.0), (3.0, 4.0, 3.0, 4.0)], 
      dtype=[('a', '<f4'), ('b', '<f4'), ('c', '<f4'), ('d', '<f4')])

关于python:numpy:命名数组的串联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18574132/

相关文章:

python - 随机矩阵所有行的快速随机加权选择

python - 如何让 mypy 接受解压的字典?

python - pandas df.apply 意外更改数据框

python - Appengine 非交互式远程脚本

python - 如何链接涉及 'index' 操作的 pandas 管道操作?

python - 使用numpy求解具有波状初始条件的输运方程

python - 如何找到重新排序的 numpy 数组的索引?

python - DataFrame.write.parquet - HIVE 或 Impala 无法读取 Parquet 文件

python - 如何使用 numpy.frompyfunc 返回元素数组而不是数组数组?

python - 如何删除xarray中的网格点?