抱歉,这个答案又长又散漫,但这就是弄清楚发生了什么的原因。数据类型的复杂性尤其被其长度所隐藏。
我得到了TypeError: cannot perform accumulate with flexible type
当我尝试你的列表时出错delimiter
。详细信息显示错误发生在LineSplitter
。无需赘述,分隔符应该是一个字符(或默认的“空白”)。
来自genfromtxt
docs:
分隔符:str、int 或序列,可选
用于分隔值的字符串。默认情况下,任何连续的
空格充当分隔符。整数或整数序列
也可以提供为每个字段的宽度。
The genfromtxt
splitter比string稍微强大一点.split
that loadtxt
用途,但不像re
分离器。
至于{TypeError}a bytes-like object is required, not 'str'
,您为几个字段指定 dtype'str'
。那是字节字符串,就像你的record
是 unicode 字符串(在 Py3 中)。但你已经意识到BytesIO(record.encode())
.
我喜欢测试genfromtxt
案例:
record = b'....'
np.genfromtxt([record], ....)
或者更好
records = b"""one line
tow line
three line
"""
np.genfromtxt(records.splitlines(), ....)
如果我让genfromtxt
推导字段类型,只使用一个分隔符,我得到 32 个字段:
In [19]: A=np.genfromtxt([record],dtype=None,delimiter='|')
In [20]: len(A.dtype)
Out[20]: 32
In [21]: A
Out[21]:
array((b'0002 00038 1', False, 3.6412123, 1.08701186, 14.1, -23.0, 69, 82, 1.8, 1.9, 1968.56, 1957.3, 3, 1.0, 3.0, 0.9, 3.0, 12.444, 0.213, 11.907, 0.189, 999, False, False, 3.64117944, 1.08706861, 1.83, 1.73, 81.0, 104.7, False, 0.0),
dtype=[('f0', 'S12'), ('f1', '?'), ('f2', '<f8'), ('f3', '<f8'), ('f4', '<f8'), ... ('f26', '<f8'), ('f27', '<f8'), ('f28', '<f8'), ('f29', '<f8'), ('f30', '?'), ('f31', '<f8')])
当我们解决整个字节和分隔符问题时
np.array([x for x in re.split(b'\|| ',record)],dtype=dform)
确实运行。我现在发现您的 dform 很复杂,具有嵌套的复合字段。
但是要定义结构化数组,您需要给它一个记录列表,例如
np.array([(record1...), (record2...), ....], dtype([(field1),(field2 ),...]))
在这里,您尝试创建一条记录。我可以将您的列表包装在一个元组中,但随后我发现该长度和dform
长度,66 v 17。如果算上所有子字段dform
可能需要 66 个值,但我们不能只用一个元组来做到这一点。
我从未尝试过从如此复杂的数组创建数组dtype
,所以我正在寻找让它发挥作用的方法。
In [41]: np.zeros((1,),dform)
Out[41]:
array([ ((0, 0, 0), '', (0.0, 0.0), (0.0, 0.0), (0, 0, 0.0, 0.0), (0.0, 0.0), 0, (0.0, 0.0, 0.0, 0.0), ((0.0, 0.0), (0.0, 0.0)), 0, '', '', (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), '', 0.0)],
dtype=[('starid', [('TYC1', '<i4'), ('TYC2', '<i4'), ('TYC3', '<i4')]), ('pflag', '<U'), ('starBearing', [('rightAscension', '<f8'), ('declination', '<f8')]), ('properMotion', [('rightAscension', '<f8'), ('declination', '<f8')]), ('uncertainty', [('rightAscension', '<i4'), ('declination', '<i4'), ('pmRA', '<f8'), ('pmDc', '<f8')]), ('meanEpoch', ....('solutionType', '<U'), ('correlation', '<f8')])
In [64]: for name in A.dtype.names:
print(A[name].dtype)
....:
[('TYC1', '<i4'), ('TYC2', '<i4'), ('TYC3', '<i4')]
<U1
[('rightAscension', '<f8'), ('declination', '<f8')]
[('rightAscension', '<f8'), ('declination', '<f8')]
[('rightAscension', '<i4'), ('declination', '<i4'), ('pmRA', '<f8'), ('pmDc', '<f8')]
[('rightAscension', '<f8'), ('declination', '<f8')]
int32
[('rightAscension', '<f8'), ('declination', '<f8'), ('pmRA', '<f8'), ('pmDc', '<f8')]
[('BT', [('mag', '<f8'), ('err', '<f8')]), ('VT', [('mag', '<f8'), ('err', '<f8')])]
int32
<U1
<U1
[('rightAscension', '<f8'), ('declination', '<f8')]
[('rightAscension', '<f8'), ('declination', '<f8')]
[('rightAscension', '<f8'), ('declination', '<f8')]
<U1
float64
我数了一下,有 34 个原始数据类型字段。大多数是“标量”,有些有 2-4 个术语,其中一个还有更深层次的嵌套。
如果我将前 2 个分隔空格替换为|
, record.split(b'|')
给我 34 个字符串。
让我们尝试一下genfromtxt
:
In [79]: np.genfromtxt([record],delimiter='|',dtype=dform)
Out[79]:
array(((2, 38, 1), '', (3.6412123, 1.08701186), (14.1, -23.0),
(69, 82, 1.8, 1.9), (1968.56, 1957.3), 3, (1.0, 3.0, 0.9, 3.0),
((12.444, 0.213), (11.907, 0.189)), 999, '', '',
(3.64117944, 1.08706861), (1.83, 1.73), (81.0, 104.7), '', 0.0),
dtype=[('starid', [('TYC1', '<i4'), ('TYC2', '<i4'), ('TYC3', '<i4')]),
('pflag', '<U'),
('starBearing', [('rightAscension', '<f8'), ('declination', '<f8')]),
('properMotion', [('rightAscension', '<f8'), ('declination', '<f8')]),
('uncertainty', [('rightAscension', '<i4'), ('declination', '<i4'), ('pmRA', '<f8'), ('pmDc', '<f8')]),
('meanEpoch', [('rightAscension', '<f8'), ('declination', '<f8')]),
('numPos', '<i4'),
('fitGoodness', [('rightAscension', '<f8'), ('declination', '<f8'), ('pmRA', '<f8'), ('pmDc', '<f8')]),
('magnitude', [('BT', [('mag', '<f8'), ('err', '<f8')]), ('VT', [('mag', '<f8'), ('err', '<f8')])]),
('starProximity', '<i4'), ('tycho1flag', '<U'), ('hipparcosNumber', '<U'),
('observedPos', [('rightAscension', '<f8'), ('declination', '<f8')]),
('observedEpoch', [('rightAscension', '<f8'), ('declination', '<f8')]),
('observedError', [('rightAscension', '<f8'), ('declination', '<f8')]), ('solutionType', '<U'), ('correlation', '<f8')])
这看起来几乎是合理的。genfromtxt
实际上可以在复合字段之间拆分值。这就是我想要尝试的更多np.array()
.
因此,如果您解决了分隔符和字节/unicode问题,genfromtxt
可以处理这个烂摊子。