NumPy 之: 使用 genfromtxt 导入数据
简介在做科学计算的时候,我们需要从外部加载数据,今天给大家介绍一下 NumPy 中非常有用的一个方法 genfromtxt。genfromtxt 可以分解成两步,第一步是从文件读取数据,并转化成为字符串。第二步就是将字符串转化成为指定的数据类型。
genfromtxt 介绍先看下 genfromtxt 的定义:
numpy.genfromtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars=" !#$%&'()*+, -./:;<=>?@[]^{|}~", replace_space='_', autostrip=False, case_sensitive=True, defaultfmt='f%i', unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None, encoding='bytes')genfromtxt 可以接受多个参数,这么多参数中只有 fname 是必须的参数,其他的都是可选的。
fname 可以有多种形式,可以是 file, str, pathlib.Path, list of str, 或者 generator。
如果是单独的 str,那么默认是本地或者远程文件的名字。如果是 list of str,那么每个 str 都被当做文件中的一行数据。如果传入的是远程的文件,这个文件会被自动下载到本地目录中。
genfromtxt 还可以自动识别文件是否是压缩类型,目前支持两种压缩类型:gzip 和 bz2。
接下来我们看下 genfromtxt 的常见应用:
使用之前,通常需要导入两个库:
from io import StringIOimport numpy as npStringIO 会生成一个 String 对象,可以作为 genfromtxt 的输入。
我们先定义一个包含不同类型的 StringIO:
s = StringIO(u"1,1.3,abcde")这个 StringIO 包含一个 int,一个 float 和一个 str。并且分割符是 ,。
我们看下 genfromtxt 最简单的使用:
In [65]: data = np.genfromtxt(s)
In [66]: dataOut[66]: array(nan)因为默认的分隔符是 delimiter=None,所以 StringIO 中的数据会被作为一个整体转换成数组,结果就是 nan。
下面我们添加一个逗号分割符:
In [67]: _ = s.seek(0)
In [68]: data = np.genfromtxt(s,delimiter=",")
In [69]: dataOut[69]: array([1. , 1.3, nan])这次有输出了,但是最后一个字符串因为不能被转换成为 float,所以得到了 nan。
注意,我们第一行需要重置 StringIO 的指针到文件的开头。这里我们使用 s.seek(0)。
那么怎么把最后一个 str 也进行转换呢?我们需要手动指定 dtype:
In [74]: _ = s.seek(0)
In [75]: data = np.genfromtxt(s,dtype=float,delimiter=",")
In [76]: dataOut[76]: array([1. , 1.3, nan])上面我们指定了所有的数组类型都是 float,我们还可以分别为数组的每个元素指定类型:
In [77]: _ = s.seek(0)
In [78]: data = np.genfromtxt(s,dtype=[int,float,'S5'],delimiter=",")
In [79]: dataOut[79]: array((1, 1.3, b'abcde'), dtype=[('f0', '<i8'), ('f1', '<f8'), ('f2', '<U')])我们分别使用 int,float 和 str 来对文件中的类型进行转换,可以看到得到了正确的结果。
除了指定类型,我们还可以指定名字,上面的例子中,我们没有指定名字,所以使用的是默认的 f0,f1,f2。看一个指定名字的例子:
In [214]: data = np.genfromtxt(s, dtype="i8,f8,S5",names=['myint','myfloat','mystring'], delimiter=",")
In [215]: dataOut[215]:array((1, 1.3, b'abcde'),dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', 'S5')])分隔符除了使用字符之外,还可以使用 index:
版权声明: 本文为 InfoQ 作者【程序那些事】的原创文章。
原文链接:【http://xie.infoq.cn/article/9c8c5386ee926d47cecd82ab3】。文章转载请联系作者。
评论