在numpy genfromtxt中,如何使用`names = True`?

myzjeezk  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(119)

这是我先前问题的跟进问题:
In numpy genfromtxt, missing_values, filling_values, excludelist, deletechars and replace_space are not working properly
这是我的测试.csv文件,其中“A 1”和“A+2”是头文件:

A 1,A+2
test&     ,1
skip,
#,
N/A,NA

有了这个字节码:

import numpy as np
test = np.genfromtxt("test.csv", 
                          delimiter = ',',
                          dtype = str,
                          names = None
                         )
test

我得到这个输出:

array([['A 1', 'A+2'],
       ['test&     ', '1'],
       ['skip', ''],
       ['N/A', 'NA']], dtype='<U10')

这里dtype='<U10'是合理的,因为'test& '中有10个字符。
但是当我将names = None更改为names = True时,我得到了这个输出。我知道标题A 1A+2已更改为A_1A2。为什么是'<U'

array([('', ''), ('', ''), ('', '')], dtype=[('A_1', '<U'), ('A2', '<U')])
0g0grzrc

0g0grzrc1#

继续我在上一个问题中使用的ipython会话,我可以用namesdtype=None创建一个结构化数组。这是我经常推荐的。

In [272]: np.genfromtxt(txt.splitlines(), delimiter=',', autostrip=True,  missing_values={0:'N/A',1:'NA'},names=True,dtype=None, filling_values={0:'nan',1:'-999'}, encoding=True)
Out[272]: 
array([('test&',    1), ('skip', -999), ('N/A', -999)],
      dtype=[('A_1', '<U5'), ('A2', '<i8')])

使用None,它推导出列dtype,在本例中,int是第二个。我得到了这个列的缺失/填充值。它仍然不适用于字符串列。这与我在上一个问题中提到的以前的尝试是一致的。缺少/填充适用于数字列。
我可以按列指定列dtype

In [273]: np.genfromtxt(txt.splitlines(), delimiter=',', autostrip=True,  names=True,dtype=['U10','U10'])
Out[273]: 
array([('test&', '1'), ('skip', ''), ('N/A', 'NA')],
      dtype=[('A_1', '<U10'), ('A2', '<U10')])

我们在其他SO中看到np.array(..., dtype=str)可以工作,但np.array(...., dtype=[('x',str), ...])不能。在第一种情况下,np.array将从所有数据中推导出所需的字符串长度。在第二个例子中,它使用dtype创建一个“空”数组,然后填充它。它无法推导出结构化数组所需的字符串长度。你得说清楚。
虽然将csv文件作为结构化数组加载很方便,但您确实需要花一些时间来了解这种类型的数组-field的含义以及字段名和dtypes。如果太多,我建议使用pandas代替。
所有names参数都与清理从文件派生的字段名有关(请参阅链接文档)。如果从结构化数组创建recarray,则字段可以作为属性访问。但是python对有效的属性名有限制(和变量名一样)。我怀疑这些限制也适用于pandas框架的列名。
pandas现在可用,recarrays没有得到那么多的使用。pandas开发人员花了更多的时间来处理诸如缺少值之类的问题。
让我重复一遍更完整文档的链接
https://numpy.org/doc/stable/user/basics.io.genfromtxt.html

dtype中的str

In [275]: np.array(['one','two','three'],dtype=str)
Out[275]: array(['one', 'two', 'three'], dtype='<U5')

In [276]: np.array([('one'),('two'),('three')],dtype=[('x',str)])
Out[276]: array([('',), ('',), ('',)], dtype=[('x', '<U')])

In [277]: np.array([('one'),('two'),('three')],dtype=[('x','U10')])
Out[277]: array([('one',), ('two',), ('three',)], dtype=[('x', '<U10')])

跳过行

据我所知,它没有一种根据内容跳过行的方法--除了comment字符(s?但是它接受来自任何可以提供给它行的东西的输入,一个打开的文件,一个通过过滤器脚本传递的文件,或者像我的演示中一样,一个字符串列表。
例如,我可以过滤掉包含'skip'的字符串:

In [281]: [line for line in txt.splitlines() if not 'skip' in line]
Out[281]: ['A 1,A+2', 'test&     ,1', '#,', 'N/A,NA']

In [283]: np.genfromtxt((line for line in txt.splitlines() if not 'skip' in line), delimiter=',',dtype=str)
Out[283]: 
array([['A 1', 'A+2'],
       ['test&     ', '1'],
       ['N/A', 'NA']], dtype='<U10')
niwlg2el

niwlg2el2#

好吧,你可以通过文档(https://numpy.org/doc/stable/reference/arrays.dtypes.html),但我会总结在这里:
< -代表little-endian(计算机以二进制形式存储数字,100101,用于处理你我都知道的数字,最右边的数字是最小的,最左边的数字是最大的,这是从右到左的方式,但计算机可以从相反的方向,从左到右,这些被称为big-endian和little-endian,在这里阅读更多,https://en.wikipedia.org/wiki/Endianness
U -代表unicode(从数字到字符的Map,因为计算机只理解数字,所以当它处理字符串时,它需要一个表来将数字Map到字符)
10 -U的大小,所以U10在一起意味着,最多10个Unicode字符,“abcdefghij”,它这样做是因为我猜你最大的文本是“test&”,我假设是10个字符长。

相关问题