使用numpy.genfromtxt时如何保留以减号开头的列名?

时间:2015-03-17 11:28:50

标签: python csv python-3.x numpy

this question类似,numpy.genfromtxt修改我的列'名称:

import numpy as np
from io import BytesIO  # https://stackoverflow.com/a/11970414/321973

str = 'x,-1,1\n0,1,1\n1,2,3'
data = np.genfromtxt(BytesIO(str.encode()), delimiter=',', names=True)
print(data.dtype.names)

产生('x', '1', '1_1')而不是所需的('x', '-1', '1')(甚至更好,('x', -1, 1))。我按照建议there尝试deletechars="""~!@#$%^&*()=+~\|]}[{';: /?>,<"""无济于事。

1 个答案:

答案 0 :(得分:2)

您看到的行为是由np.genfromtxt使用NameValidatorhere自动从字段名称中删除某些非字母数字字符的事实引起的。

字段名称包含'-'字符非常合法,例如:

x = np.array((1,), dtype=[('-1', 'i')])
print(x['-1'])
# 1

事实上,从np.genfromtxt返回的三个修改后的字段名称中,有两个也不是#34;有效的Python标识符&#34; ('1''1_1',因为它们以数字开头。)

因此,只要您绕过np.genfromtxt来设置字段名称,就可以构建您描述的数组。一种方法是初始化一个空数组,明确指定字段名称和dtypes,然后用其余的字符串内容填充它:

names = str.splitlines()[0].split(',')
types = ('i',) * 3
dtype = zip(names, types)

data = np.empty(2, dtype=dtype)
data[:] = np.genfromtxt(BytesIO(str.encode()), delimiter=',', dtype=dtype,
                        skiprows=1)
print(repr(data))
# array([(0, 0, 1), (1, 0, 2)], 
#       dtype=[('x', '<i4'), ('-1', '<i4'), ('1', '<i4')])

然而,仅仅因为你并不意味着你应该 - 在你的一个字段名中加上'-'可能会产生其他不可预测的后果。最安全的选择是坚持只使用有效的Python标识符作为字段名称。