我正在尝试使用numpy.lib.recfunctions append_fields函数将数组附加到numpy recarray。
我收到" TypeError:数据类型未被理解"如果重新排列字段名称是unicode,则会出错。
这种行为是否按设计进行,如果有,是否有解决办法?
在Win32计算机上使用python 2.7。
下面的代码演示了这个问题(原谅额外的日期 - 时间操作 - 我想尽可能地将问题创建到我原来的错误中):
from datetime import datetime
import numpy as np
import numpy.lib.recfunctions as RF
x1=np.array([1,2,3,4])
x2=np.array(['a','dd','xyz','12'])
x3=np.array([1.1,2,3,4])
# this works
FileData = np.core.records.fromarrays([x1,x2,x3],names=['a','b','c'])
# this doesnt
#FileData = np.core.records.fromarrays([x1,x2,x3],names=[u'a',u'b',u'c'])
sDT = ['1/1/2000 12:00:00','1/1/2000 13:00:00','1/1/2000 14:00:00','1/1/2000 15:00:00']
pDT = [datetime.strptime(x, '%d/%m/%Y %H:%M:%S') for x in sDT]
# convert to unix timestamp
DT = [ (np.datetime64(dt) - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's') for dt in pDT]
# add datetime to recaray
print FileData.dtype
FileData = RF.append_fields(FileData,'DateTime', data=DT) #, dtypes='f8'
print FileData.dtype
答案 0 :(得分:2)
具有unicode
名称的代码在Python3
下正常运行,其中unicode是默认字符串类型。
编辑:最初我认为问题在于蒙面数组。但是通过进一步的测试,我得出结论,真正的问题是dtype
是否可以接受unicode(在py2情况下)名称。通常名称必须是字符串(但是版本定义了它们)。但是定义dtype的字典样式允许使用unicode名称。这是fromarrays
工作原因的根源,而不是append_fields
。
我离开了蒙面数组讨论,因为这是你接受的。
在2.7下,完整的错误堆栈是:
File "stack28586238.py", line 22, in <module>
FileData = RF.append_fields(FileData,'DateTime', data=DT) #, dtypes='f8'
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 403, in merge_arrays
return seqarrays.view(dtype=seqdtype, type=seqtype)
File "/usr/local/lib/python2.7/site-packages/numpy/core/records.py", line 501, in view
return ndarray.view(self, dtype, type)
File "/usr/local/lib/python2.7/site-packages/numpy/ma/core.py", line 2782, in __array_finalize__
_mask = getattr(obj, '_mask', make_mask_none(obj.shape, odtype))
File "/usr/local/lib/python2.7/site-packages/numpy/ma/core.py", line 1566, in make_mask_none
result = np.zeros(newshape, dtype=make_mask_descr(dtype))
File "/usr/local/lib/python2.7/site-packages/numpy/ma/core.py", line 1242, in make_mask_descr
return np.dtype(_recursive_make_descr(ndtype, np.bool))
TypeError: data type not understood
错误发生在屏蔽数组函数中,如:
之类的调用np.ma.make_mask_none((3,),dtype=[(u'value','f4')])
我在之前的SO问题中遇到过掩码数组的问题(不久之前)。我必须看看它是否相关。
Is the mask of a structured array supposed to be structured itself?
没有直接相关,但在混合蒙面数组和结构化数组时确实指出了一些错误。
Adding datetime field to recarray
关于add_fields
关注datetime
类型的问题,是您之前提出的问题。
通过添加usemask=False
我将错误转移到另一个点,在那里它尝试从两个组件dtype列表构建dtype
:np.dtype(base.dtype.descr + data.dtype.descr)
。
在2.7中,我们可以构造一个带有unicode名称的record array
:
In [11]: np.core.records.fromarrays([[0,1]],names=[u'test'])
Out[11]:
rec.array([(0,), (1,)],
dtype=[(u'test', '<i4')])
但是我无法使用unicode名称直接构造dtype
:
In [12]: np.dtype([(u'test', int)])
...
TypeError: data type not understood
似乎通常dtype名称必须是字符串。在python3
中,np.dtype([(b'test', int)])
会产生相同的错误。
同样在py3
np.core.records.fromarrays([[0,1]],names=[b'test'])
生成ValueError: field names must be strings
。
np.core.records.fromarrays
允许使用unicode,因为它使用format_parser
:
p=np.format_parser(['int'],[u'test'],[])
p.dtype
# dtype([(u'test', '<i4')])
这是有效的,因为 dtype定义的字典样式接受unicode :
np.dtype({'names':[u'test'],'formats':['int']})
以下是使用unicode名称合并两个结构化数组的示例(在py2中工作):
In [53]: dt1 = np.dtype({'names':[u'test1'],'formats':['int']})
In [54]: dt2 = np.dtype({'names':[u'test2'],'formats':['float']})
In [55]: dt12 = np.dtype({'names':[u'test1',u'test2'],'formats':['int','float']})
In [56]: arr1 = np.array([(x,) for x in [1,2,3]],dtype=dt1)
In [57]: arr2 = np.array([(x,) for x in [1,2,3]],dtype=dt2)
In [58]: arr12 = np.zeros((3,),dtype=dt12)
In [59]: RF.recursive_fill_fields(arr1,arr12)
...
In [60]: RF.recursive_fill_fields(arr2,arr12)
Out[60]:
array([(1, 1.0), (2, 2.0), (3, 3.0)],
dtype=[(u'test1', '<i4'), (u'test2', '<f8')])
append_fields
基本上做了这个(添加了一些花里胡哨的东西)。
我已在https://github.com/numpy/numpy/issues/2407添加了评论
dtype field names cannot be unicode (Trac #1814)