csv 使用numpy loadtxt或genfromtxt时如何指定列名?

tmb3ates  于 2023-05-04  发布在  其他
关注(0)|答案(3)|浏览(132)

我有下面的示例文件(test.csv),第一行是标题:

#a  |b    |c
foo |fooo |foooo
bar |barr |barrr

命令:

numpy.loadtxt('test.csv', delimiter='|', dtype=str)

效果很好。输出为

array([['foo ', 'fooo ', 'foooo'],
       ['bar ', 'barr ', 'barrr']], dtype='<U5')

但是,如果我尝试为列指定名称:

numpy.loadtxt('test.csv', delimiter='|', dtype=[('a', str), ('b', str), ('c', str)])

我得到:

array([('', '', ''), ('', '', '')],
      dtype=[('a', '<U'), ('b', '<U'), ('c', '<U')])

与使用genfromtxt自动推断名称相同:

numpy.genfromtxt('test.csv', delimiter='|', names=True, dtype=str)

输出

array([('', '', ''), ('', '', '')],
      dtype=[('a', '<U'), ('b', '<U'), ('c', '<U')])

即使名称被正确识别。我做错了什么?我肯定我错过了一些明显的东西。

oxcyiej7

oxcyiej71#

In [32]: txt='''#a  |b    |c
...: foo |fooo |foooo
...: bar |barr |barrr'''.splitlines()

dtype=None可以推断字段的数据类型;

In [36]: np.genfromtxt(txt, delimiter='|', dtype=None, names=True, encoding=None)
Out[36]: 
array([('foo ', 'fooo ', 'foooo'), ('bar ', 'barr ', 'barrr')],
      dtype=[('a', '<U4'), ('b', '<U5'), ('c', '<U5')])

使用names=True,它从第一行推断字段名称(注解与否)
没有名字,它是一个2d数组(跳过注解行):

In [37]: np.genfromtxt(txt, delimiter='|', dtype=None, encoding=None)
Out[37]: 
array([['foo ', 'fooo ', 'foooo'],
       ['bar ', 'barr ', 'barrr']], dtype='<U5')

genfromtxt非常灵活,但需要很多参数。基本上,它将数据加载为列表的列表(由分隔符分隔的字符串)。然后,它将从中构建数组。因此,对如何从列表的列表和dtype构造数组的一些理解会有所帮助。
正如我评论的:

In [38]: np.dtype('U5,float,int').itemsize
Out[38]: 32
In [39]: np.array((1,2,3),np.dtype('U5,float,int'))
Out[39]: array(('1', 2., 3), dtype=[('f0', '<U5'), ('f1', '<f8'), ('f2', '<i4')])

In [41]: np.array((1,2,3), str)
Out[41]: array(['1', '2', '3'], dtype='<U1')

编辑

显式字段名称:

In [42]: np.genfromtxt(txt, delimiter='|', dtype=None, 
    names=['A','B','C'], encoding=None)
Out[42]: 
array([('foo ', 'fooo ', 'foooo'), ('bar ', 'barr ', 'barrr')],
      dtype=[('A', '<U4'), ('B', '<U5'), ('C', '<U5')])
iyfjxgzm

iyfjxgzm2#

如果你想使用列名,我建议使用pandas。

import pandas as pd
df = pd.read_csv('test.csv', sep='|')

如果要修复列名和值中的前导空格和尾随空格,可以执行以下操作:

df = pd.read_csv('test.csv', sep='|')
df.columns = df.columns.str.strip()
df = df.applymap(str.strip)
> print(df)

    #a     b      c
0  foo  fooo  foooo
1  bar  barr  barrr
4uqofj5v

4uqofj5v3#

如果你坚持使用numpy,那么你可以这样做:

import np as np
arr = np.recfromcsv('text.csv', delimiter='|', encoding='utf-8', dtype=None)
arr2 = np.array(
    [
        ('foo ', 'fooo ', 'foooo'),
        ('bar ', 'barr ', 'barrr'),
    ],
    dtype=[('a', '<U4'), ('b', '<U5'), ('c', '<U5')],
)

> print(all(arr == arr2))
True

相关问题