【问题标题】:How to preserve column names starting with a minus when using numpy.genfromtxt?使用 numpy.genfromtxt 时如何保留以减号开头的列名?
【发布时间】:2015-05-19 19:29:45
【问题描述】:

类似于this questionnumpy.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 不是。
  • 最后,我想顺便获得一个np.meshgrid,所以请继续阻止我的XY问题;)
  • @jonrsharpe 你的意思是不是所有的字符串都是有效的?是否有有效标识符列表?
  • 我不确定,但this doc 指出““名称”必须是有效的 Python 标识符”
  • @jonrsharpe 不,它们不需要是有效的标识符:x = np.array((1,), dtype=[('-1', 'i')]); x['-1'] 工作得很好

标签: python csv python-3.x numpy


【解决方案1】:

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

字段名称包含'-' 字符是完全合法的,例如:

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

事实上,您从np.genfromtxt 返回的修改后的字段名称中有三分之二也不是“有效的 Python 标识符”('1''1_1',因为它们以数字开头)。

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

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 标识符作为字段名。

【讨论】:

    猜你喜欢
    • 2017-03-18
    • 2016-05-14
    • 2018-08-24
    • 2017-01-05
    • 2021-06-16
    • 2022-11-17
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    相关资源
    最近更新 更多