假设我使用相同的dtype制作两个重组并叠加它们:
>>> import numpy as np
>>> dt = [('foo', int), ('bar', float)]
>>> a = np.empty(2, dtype=dt).view(np.recarray)
>>> b = np.empty(3, dtype=dt).view(np.recarray)
>>> c = np.hstack((a,b))
虽然a
和b
是重新排列,但c
不是:
>>> c.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute 'foo'
>>> d = c.view(np.recarray)
>>> d.foo
array([ 0, 111050731618561, 0,
7718048, 8246760947200437872])
我显然可以再次将其变成一个重新组合,如上面d
所示,但这很不方便。有没有理由为什么堆叠两个重组不会产生另一个重新排列?
答案 0 :(得分:6)
我不知道。很可能它是一个从未实现过的bug /功能。 numpy.hstack
基本上是numpy.core.fromnumeric
中函数的包装器。数字是numpy的两个前身之一。 numpy中的大多数函数都有一个约定,通过调用输出上输入的方法__array_wrap__
来输出与输入相同的类型,结果输出应该具有相同的数据,但是在新类中“包装” 。也许“包装”的概念不是数字的,只要添加到此函数中。
您可以使用此技术制作更智能的堆叠功能
def hstack2(arrays) :
return arrays[0].__array_wrap__(numpy.hstack(arrays))
这适用于重组和常规数组
>>> f = hstack2((a,b))
>>> type(f)
<class 'numpy.core.records.recarray'>
>>> f.foo
array([ 140633760262784, 111050731618561, 140633760262800,
7536928, 8391166428122670177])
>>> x = numpy.random.rand(3)
>>> y = numpy.random.rand(2)
>>> z = hstack2((x,y))
>>> type(z)
<type 'numpy.ndarray'>
我不确定你的计划是什么,但你可能想问一下numpy mailing list是否有比使用文档化但双重强调的方法更好的方法,以及他们的推理是什么不是自己做包装。
答案 1 :(得分:6)
或者,numpy.lib.recfunctions
中有一些辅助工具,我偶然发现了here。此模块具有合并和堆叠recarrays
:
from numpy.lib.recfunctions import stack_arrays
c = stack_arrays((a, b), asrecarray=True, usemask=False)
c.foo
>>> array([ 140239282560000, 4376479720, -4611686018427387904,
4358733828, 4365061216])
如果想要向recarray
添加额外的列,可以使用merge_arrays
来完成:
import numpy as np
from numpy.lib.recfunctions import merge_arrays
dt1 = [('foo', int), ('bar', float)]
dt2 = [('foobar', int), ('barfoo', float)]
aa = np.empty(6, dtype=dt1).view(np.recarray)
bb = np.empty(6, dtype=dt2).view(np.recarray)
cc = merge_arrays((aa, bb), asrecarray=True, flatten=True)
type(cc)
>>> numpy.core.records.recarray
(虽然不是问题的答案,但我将后一个例子作为参考发布)
答案 2 :(得分:-1)