供参考,以下是完整的回溯信息:
从一个结构化数组开始,其中包含一条记录:
array([('1', 17, 123.45)],
dtype=[('field_a', 'S32'), ('field_b', '<i4'), ('field_c', '<f8')])
在第一次添加后,我们得到了一个掩码数组,仍然只有1条记录:
masked_array(data = [('1', 17, 123.45, '1', '3')],
mask = [(False, False, False, False, False)],
fill_value = ('N/A', 999999, 1e+20, 'N', 'N'),
dtype = [('field_a', 'S32'), ('field_b', '<i4'), ('field_c', '<f8'), ('field_d', 'S1'), ('field_e', 'S1')])
错误似乎更多地与掩码数组代码有关,而不是
recfunctions
- 尽管我需要查看代码才能了解为什么要使用
ravel
。
Traceback (most recent call last):
File "stack36440557.py", line 15, in <module>
numpy_array2 = rcfuncs.append_fields( numpy_array1, "field_f", data=["123456"] ,usemask=False)
File "/usr/local/lib/python2.7/site-packages/numpy/lib/recfunctions.py", line 633, in append_fields
base = merge_arrays(base, usemask=usemask, fill_value=fill_value)
File "/usr/local/lib/python2.7/site-packages/numpy/lib/recfunctions.py", line 389, in merge_arrays
seqarrays = seqarrays.ravel()
File "/usr/local/lib/python2.7/site-packages/numpy/ma/core.py", line 4022, in ravel
r = ndarray.ravel(self._data).view(type(self))
TypeError: descriptor 'ravel' requires a 'numpy.ndarray' object but received a 'numpy.void'
因此,一种解决方法是关闭masked_arrays
的使用。除非添加的字段缺少一些数据,否则不需要使用它。
另一种方法是将第一个参数放在列表中:
rcfuncs.append_fields( [numpy_array1], "field_f", data=['12345'])
append_fields(base, ....)
调用
merge_arrays(base, usemask=usemask, fill_value=fill_value)
这将进而调用
base.ravel() # now call seq_arrays
首先它会检查它的长度是否为1
if (len(seqarrays) == 1):
seqarrays = np.asanyarray(seqarrays[0])
对于一个简单的结构化数组y
及其掩码版本ym
:
In [405]: y
Out[405]:
array([(b'xxx', 1)],
dtype=[('f0', 'S5'), ('f1', '<i4')])
In [406]: ym=np.ma.masked_array(y)
这个长度为1的动作会生成另一个用于常规结构化数组的数组:
In [407]: np.asanyarray(y[0])
Out[407]:
array((b'xxx', 1),
dtype=[('f0', 'S5'), ('f1', '<i4')])
但是对于被屏蔽的那个,使用一个
void
(结构化数组记录/元素)。
In [408]: np.asanyarray(ym[0])
Out[408]: (b'xxx', 1)
In [409]: type(np.asanyarray(ym[0]))
Out[409]: numpy.ma.core.mvoid
np.asanyarray(ym[0]).ravel()
产生了这个 TypeError 错误。
如果基础是一个列表 [ym]
,那么它只会提取 ym
。 如果基础是 (2,) 或更长,则不会通过此语句。
我还没有想到解决方法 - 除了将掩码数组传递到列表中的用户级别修补程序之外。
一个可能的解决方法是简单地删除 append_fields
中的 base=merge_arrays(base...)
这一行。但我需要知道它首先出现的原因。其目的可能是清理某些 base
数组输入。
单元测试文件 test/test_recfunctions.py
在注释掉此行后可以正常运行。
我已在旧的 numpy
问题上添加了评论。
https://github.com/numpy/numpy/issues/2346
numpy
代码中轻度使用的区域 - 请注意您需要单独导入rcfuncs
。 - hpaulj