当尝试连接具有dtype字符串但具有不同长度的字段的记录数组时,连接失败。
正如您在下面的示例中所看到的,如果'f1'长度相同但是失败则连接有效,如果没有。
In [1]: import numpy as np
In [2]: a = np.core.records.fromarrays( ([1,2], ["one","two"]) )
In [3]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]) )
In [4]: c = np.core.records.fromarrays( ([6], ["six"]) )
In [5]: np.concatenate( (a,c) )
Out[5]:
array([(1, 'one'), (2, 'two'), (6, 'six')],
dtype=[('f0', '<i8'), ('f1', '|S3')])
In [6]: np.concatenate( (a,b) )
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/u/jegannas/<ipython console> in <module>()
TypeError: expected a readable buffer object
但是,如果我们只是连接数组(而不是记录),它会成功,尽管字符串的大小不同。
In [8]: np.concatenate( (a['f1'], b['f1']) )
Out[8]:
array(['one', 'two', 'three', 'four', 'three'],
dtype='|S5')
这是连接记录时连接的错误还是预期的行为。我只想通过以下方法来克服这个问题。
In [10]: np.concatenate( (a.astype(b.dtype), b) )
Out[10]:
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')],
dtype=[('f0', '<i8'), ('f1', '|S5')]
但问题是我必须经历所有重组,我连接并找到最大的字符串长度,我必须使用它。如果我在记录数组中有多个字符串列,我还需要跟踪其他一些事项。
你认为什么是解决这个问题的最好方法,至少目前是什么?
答案 0 :(得分:6)
发表完整的答案。正如Pierre GM所建议的那样:
import numpy.lib.recfunctions
给出一个解决方案。然而,执行您想要的功能是:
numpy.lib.recfunctions.stack_arrays((a,b), autoconvert=True, usemask=False)
(usemask=False
只是为了避免创建一个你可能没有使用的蒙面数组。重要的是autoconvert=True
强制转换a
的{{1} } dtype
到"|S3"
)。
答案 1 :(得分:2)
如果您未指定dtype,np.rec.fromarrays
(又名np.core.records.fromarrays
)会尝试为您猜测dtype。因此,
In [4]: a = np.core.records.fromarrays( ([1,2], ["one","two"]) )
In [5]: a
Out[5]:
rec.array([(1, 'one'), (2, 'two')],
dtype=[('f0', '<i4'), ('f1', '|S3')])
注意f1
列的dtype是一个3字节的字符串。
您无法连接np.concatenate( (a,b) )
,因为numpy看到a
和b
的dtypes不同,并且不会更改较小字符串的dtype以匹配较大的字符串。< / p>
如果您知道可用于所有数组的最大字符串大小,则可以从头开始指定dtype:
In [9]: a = np.rec.fromarrays( ([1,2], ["one","two"]), dtype = [('f0', '<i4'), ('f1', '|S8')])
In [10]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]), dtype = [('f0', '<i4'), ('f1', '|S8')])
然后连接将按预期工作:
In [11]: np.concatenate( (a,b))
Out[11]:
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')],
dtype=[('f0', '<i4'), ('f1', '|S8')])
如果您事先不知道字符串的最大长度,可以将dtype指定为“object”:
In [35]: a = np.core.records.fromarrays( ([1,2], ["one","two"]), dtype = [('f0', '<i4'), ('f1', 'object')])
In [36]: b = np.core.records.fromarrays( ([3,4,5], ["three","four","three"]), dtype = [('f0', '<i4'), ('f1', 'object')])
In [37]: np.concatenate( (a,b))
Out[37]:
array([(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), (5, 'three')],
dtype=[('f0', '<i4'), ('f1', '|O4')])
这不会像'|Sn'
的dtype那样节省空间(对于某些整数n
),但至少它会允许您执行concatenate
操作。
答案 2 :(得分:2)
numpy.lib.recfunctions.merge_arrays
能为你效力吗? recfunctions
是一个鲜为人知的子包,没有广告,它有点笨拙但有时可能有用。