Numpy.genfromtxt 删除 dtype.names 中的方括号



我正在尝试使用 numpy.genfromtxt 从文件中读取数据。 我将 names 参数设置为以逗号分隔的字符串列表,例如

names = ['a', '[b]', 'c']

但是,当返回数组时,dtype.names 值返回('a', 'b', 'c')

deletechars参数未设置或强制None 。 我已经检查过,创建一个带有dtype的numpy.ndarray,该dtype具有带方括号的命名列,因此一定是genfromtxt正在删除方括号。 有没有办法关闭这个意外的功能?

请注意,如果 names 参数设置为 True ,也会发生此行为。 我已经在 numpy 版本 1.6.1 和 1.9.9 中对此进行了测试

我之前在 numpy 问题跟踪器和邮件列表中抱怨过这种字段名称重整行为。它也出现在之前关于SO的几个问题中。

事实上,默认情况下,即使您通过将字符串列表作为 names= 参数直接指定字段名称,np.genfromtxt也会破坏字段名称:

import numpy as np
from io import BytesIO
s = '[5],name with spaces,(x-1)!n1,2,3n4,5,6'
x = np.genfromtxt(BytesIO(s), delimiter=',', names=True)
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], 
#       dtype=[('5', '<f4'), ('name_with_spaces', '<f4'), ('x1n1', '<f4')])
names = s.split(',')[:3]
x = np.genfromtxt(BytesIO(s), delimiter=',', skip_header=1, names=names)
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], 
#       dtype=[('5', '<f4'), ('name_with_spaces', '<f4'), ('x1n1', '<f4')])

尽管包含非字母数字字符的字段名称是完全合法的,但还是会发生这种情况:

x2 = np.empty(2, dtype=dtype)
x2[:] = [(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]
print(repr(x2))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], 
#       dtype=[('[5]', '<f4'), ('name with spaces', '<f4'), ('(x-1)!n1', '<f4')])

这种行为的逻辑逃脱了我。


如您所见,将None作为deletechars=参数传递并不足以防止这种情况发生,因为此参数在内部初始化为numpy._iotools.NameValidator中的一组默认字符。

但是,您可以改为传递空序列:

x = np.genfromtxt(BytesIO(s), delimiter=',', names=True, deletechars='')
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)], 
#       dtype=[('[5]', '<f8'), ('name_with_spaces', '<f8'), ('(x-1)!', '<f8')])

这可以是空字符串、列表、元组等。只要它的长度为零就没关系。

在字符串格式问题中(参数与下划线)我发现除了deletechars参数之外还需要dtype=None

https://stackoverflow.com/a/32540939/901925

In [168]: np.genfromtxt([b'1,2,3'],names=['a','[b]','xcx'],delimiter=',',deletechars='',dtype=None)
Out[168]: 
array((1, 2, 3), 
      dtype=[('a', '<i4'), ('[b]', '<i4'), ('xcx', '<i4')])

使用默认dtype(浮点),使用 deletechars,但名称通过第二个验证器,easy_dtype验证器不会获取此参数。

In [170]: np.genfromtxt([b'1,2,3'],names=['a','[b]','xcx'],delimiter=',',deletechars='x')
Out[170]: 
array((1.0, 2.0, 3.0), 
      dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])

https://github.com/numpy/numpy/pull/4649


加载后可以更改字段名称:

In [205]: data=np.genfromtxt([b'1 2 3 txt'],names=['a','b','c','d'],dtype=[int,float,int,'S4'])
In [206]: data.dtype.names
Out[206]: ('a', 'b', 'c', 'd')
In [207]: data.dtype.names=['a','[b]','*c*','d']
In [208]: data
Out[208]: 
array((1, 2.0, 3, 'txt'), 
      dtype=[('a', '<i4'), ('[b]', '<f8'), ('*c*', '<i4'), ('d', 'S4')])

这适用于从文件本身获取的名称:

In [212]: data=np.genfromtxt([b'a [b] *c* d','1 2 3 txt'],dtype=[int,float,int,'S4'],names=True)

相关内容

  • 没有找到相关文章

最新更新