尝试将字段追加到大小为1的结构化数组时,我遇到了运行时错误。我在下面写了一个简单的例子:
import numpy as np
import numpy.lib.recfunctions as rcfuncs
dtype_ = np.dtype( { 'names': ["field_a","field_b","field_c"]
, 'formats': ['S32', 'i4', 'f8']}
)
data_ = [("1",17, 123.45)]
numpy_array = np.array(data_, dtype_)
# append 2 fields
numpy_array = rcfuncs.append_fields( numpy_array,["field_d","field_e"],data=[ "1","3" ] )
# append 1 field fails :(
numpy_array = rcfuncs.append_fields( numpy_array, "field_f", data=["123456"] )
我收到了错误:
TypeError: descriptor 'ravel' requires a 'numpy.ndarray' object but received a 'numpy.void'
同样,如果我'反转'追加,那么附加两个字段的语句将会失败:
# append 1 field
numpy_array = rcfuncs.append_fields( numpy_array, "field_f", data=["123456"] )
# append 2 fields fails :(
numpy_array = rcfuncs.append_fields( numpy_array,["field_d","field_e"],data=[ "1", "3" ] )
我正在使用python 2.7.11和numpy 1.11.0运行,当初始数组的大小超过2时,我没有问题。
如何解决类型错误?
由于
答案 0 :(得分:2)
将可选参数usemask设置为False
时,我们没有得到TypeErrornumpy_array = \
rcfuncs.append_fields(numpy_array, "field_f", data=["123456"], usemask=False)
numpy_array = \
rcfuncs.append_fields(numpy_array,["field_d","field_e"],data=[ "1", "3" ], usemask=False)
答案 1 :(得分:1)
供参考,这是完整的追溯
从结构化数组开始,只有一条记录:
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
但首先它检查它是长度
# Only one item in the input sequence ?
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,)或更长,则不会通过此语句。
我还没有想过修复 - 其他用户级别的kludge将掩盖的数组传递到列表中。
可能的解决方法是简单地删除此base=merge_arrays(base...)
行(在append_fields
中)。但我需要知道为什么它首先存在。目的可能是清理某些base
数组输入。
单元测试文件test/test_recfunctions.py
运行正常,此行已注释掉。
我已将此评论添加到旧的numpy
问题