【问题标题】:read values from a text file using numpy loadtxt function使用 numpy loadtxt 函数从文本文件中读取值
【发布时间】:2016-09-04 14:30:19
【问题描述】:

我有一个这样的文件:

label1, value1, value2, value3,
label2, value1, value2, value3,
...

我想使用 numpy loadtxt 函数读取它,这样我就可以将每个标签及其值放在一个数组中,所以最终结果将是一个数组数组,其中每个数组都包括标签和一个这样的特征数组:

array([[label1, [value1, value2, value3]],
       [label2, [value1, value2, value3]]])

我尝试了以下方法,但没有成功:

c = StringIO(u"text.txt")
np.loadtxt(c,
   dtype={'samples': ('label', 'features'), 'formats': ('s9',np.float)},
   delimiter=',', skiprows=0)

有什么想法吗?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    最现代、最通用的方法是使用 pandas,它的解析器有更多选项和管理标签。

    假设您的文件包含:

    A,7,5,1
    B,4,2,7
    

    然后:

    In [29]: import pandas as pd
    In [30]: df=pd.read_csv('data.csv',sep=',',header=None,index_col=0)
    
    In [31]: df
    Out[31]: 
       1  2  3
    0         
    A  7  5  1
    B  4  2  7
    

    您现在可以轻松地将其转换为结构数组:

    In [32]: a=df.T.to_records(index=False)
    Out[32]: 
    rec.array([(7, 4), (5, 2), (1, 7)], 
              dtype=[('A', '<i8'), ('B', '<i8')])
    
    In [33]: a['A']
    Out[33]: array([7, 5, 1], dtype=int64)
    

    使用loadtext,您将不得不手动执行大量低级操作。

    【讨论】:

      【解决方案2】:

      您在定义 dtype 方面是正确的。您只是缺少字段形状。

      我会演示:

      “文本”文件 - 行列表(Py3 中的字节):

      In [95]: txt=b"""label1, 12, 23.2, 232
         ....: label2, 23, 2324, 324
         ....: label3, 34, 123, 2141
         ....: label4, 0, 2, 3
         ....: """
      
      In [96]: txt=txt.splitlines()
      

      一个 dtype 有 2 个字段,一个带有字符串,另一个带有浮点数(3 个用于“字段形状”):

      In [98]: dt=np.dtype([('label','U10'),('values', 'float',(3))])
      
      In [99]: data=np.genfromtxt(txt,delimiter=',',dtype=dt)
      
      In [100]: data
      Out[100]: 
      array([('label1', [12.0, 23.2, 232.0]), ('label2', [23.0, 2324.0, 324.0]),
             ('label3', [34.0, 123.0, 2141.0]), ('label4', [0.0, 2.0, 3.0])], 
            dtype=[('label', '<U10'), ('values', '<f8', (3,))])
      
      In [101]: data['label']
      Out[101]: 
      array(['label1', 'label2', 'label3', 'label4'], 
            dtype='<U10')
      
      In [103]: data['values']
      Out[103]: 
      array([[  1.20000000e+01,   2.32000000e+01,   2.32000000e+02],
             [  2.30000000e+01,   2.32400000e+03,   3.24000000e+02],
             [  3.40000000e+01,   1.23000000e+02,   2.14100000e+03],
             [  0.00000000e+00,   2.00000000e+00,   3.00000000e+00]])
      

      使用此定义,数值可以作为二维数组访问。像这样的子数组不受欢迎。

      dtype 可以用字典语法指定,但我更熟悉元组列表形式。

      等效的数据类型规范:

      np.dtype("U10, (3,)f")
      np.dtype({'names':['label','values'], 'formats':['S10','(3,)f']})
      np.genfromtxt(txt,delimiter=',',dtype='S10,(3,)f')
      

      =================================

      我认为这个 txt,如果用 dtype=None 解析会产生

      In [30]: y
      Out[30]: 
      array([('label1', 12.0, 23.2, 232.0), ('label2', 23.0, 2324.0, 324.0),
             ('label3', 34.0, 123.0, 2141.0), ('label4', 0.0, 2.0, 3.0)], 
            dtype=[('f0', '<U10'), ('f1', '<f8'), ('f2', '<f8'), ('f3', '<f8')])
      

      可以转换为子字段形式

      y.view(dt)
      

      只要底层数据表示(被视为字节的平面列表)兼容(此处为 10 个 unicode 字符(40 个字节)和 3 个浮点数,每条记录),它就可以工作。

      【讨论】:

      • 这对我来说非常有用,但我得到一个错误“元组的大小必须匹配字段数。”我的实际 txt 文件与发布的示例相同,但是有一个标签和 22 个其他值,所以我的代码是 txt=StringIO(u"dataset.txt") dt=np.dtype([('label','U10'),('features', 'float',(22))]) data=np.genfromtxt(txt,delimiter=',',dtype=dt)
      • 是的,总数字段,命名或子数组,需要与文件中的列数相匹配,或在您的usecols 参数中。
      • 是的,我注意到了,但是,我不知道为什么它不起作用并向我显示了那个错误..
      • 尝试dtype=None 以查看它从数据中推断出的数据类型。这可能会帮助您更正定义。在限制范围内,您甚至可以使用 astypeview 从该 dtype 转换为您的。
      猜你喜欢
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      相关资源
      最近更新 更多