访问数据是使用本书所介绍的这些工具的第一步。我会着重介绍pandas的数据输入与输出,虽然别的库中也有不少以此为目的的工具。
输入输出通常可以划分为几个大类:读取文本文件和其他更高效的磁盘存储格式,加载数据库中的数据,利用Web API操作网络资源。
读写文本格式数据
pandas提供了一些用于将表格数据读取为DataFrame对象的函数。下表对这些内容进行了总结,其中read_csv和read_table今后用的应该是最多的。
函数 | 说明 |
---|---|
read_csv | 从文件、URL、文件型对象中加载带分隔符的数据,默认分隔符为逗号 |
read_table | 从文件、URL、文件型对象中加载带分隔符的数据,默认分隔符为制表符(‘\t’) |
read_fwf | 读取定宽列格式数据(无分隔符) |
read_clipboard | 读取剪贴板数据 |
read_excel | 顾名思义读取excel数据 |
read_hdf | 读取pandas写的HDF5文件 |
read_html | 读取HTML中的所有表格 |
read_json | 读取json字符串数据 |
read_msgpack | 二进制编码的pandas数据 |
read_pickle | 读取python pickle格式中的任意数据 |
read_sas | 读取存储于SAS系统自定义存储数据集 |
read_sql | 读取SQL查询结果为pandas的DataFrame |
read_stata | 读取Stata文件数据集 |
read_feather | 读取Feather二进制文件格式 |
本文将会简要介绍一下这些函数在把文本数据转化为DataFrame时所用到的使用方法。这些函数主要可以分为如下几个类别:
- 索引:将一个或多个列当做返回的DataFrame处理,以及是否从文件、用户获取列名。
- 类型推断和数据转换:包括用户定义值的转换、和自定义的缺失值标记列表等。
- 日期解析:包括组合功能,比如将分散在多个列中的日期时间信息组合成结果中的单个列。
- 迭代:支持对大文件进行逐块迭代。
- 不规整数据问题:跳过一些行、页脚、注释或其他一些不重要的东西(比如由成千上万个逗号隔开的数值数据)。
因为我们在日常的数据处理中所遇到的数据集可能会十分混乱,一些数据加载的函数(尤其是read_csv)的选项会变得十分复杂。面对不同的参数,我们常常会十分头疼。pandas文档有这些参数的解释与示例,如果你读取某个文件很困难,就可以多对这些文档进行学习。
日期和其他自定义类型的处理需要花费更多的精力。首先我们来看一看一个用逗号分隔的CSV文件:
In [8]: !type examples/ex1.csv
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
这里win使用的是type来查看文件中的内容,如果你用的是Linux可以使用cat来完成相同的操作。
由于是用逗号分割,所以我们可以通过read_csv将其读取到要给DataFrame中:
In [9]: df = pd.read_csv('examples/ex1.csv')
In [10]: df
Out[10]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
当然我们还可以用read_table指定分隔符:
In [11]: pd.read_table('examples/ex1.csv', sep=',')
Out[11]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
但是并不是所有的文件都存在标签行,如下:
In [12]: !type examples/ex2.csv
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
要读取这种文件,我们可以让pandas为它分配默认的列名,也可以自定义:
In [13]: pd.read_csv('examples/ex2.csv', header=None)
Out[13]:
0 1 2 3 4
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
In [14]: pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])
Out[14]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
有些情况下,有些表格可能不是用固定的分隔符去分隔字段的(比如空白符或其它模式)。看看下面这个文本文件:
In [20]: list(open('examples/ex3.txt'))
Out[20]:
[' A B C\n',
'aaa -0.264438 -1.026059 -0.619500\n',
'bbb 0.927272 0.302904 -0.032399\n',
'ccc -0.264273 -0.386314 -0.217601\n',
'ddd -0.871858 -0.348382 1.100491\n']
虽然可以手动对数据进行规整,这里的字段是被数量不同的空白字符间隔开的。这种情况下,你可以传递一个正则表达式作为read_table的分隔符。可以用正则表达式表达为\s+,于是有:
In [21]: result = pd.read_table('examples/ex3.txt', sep='\s+')
In [22]: result
Out[22]:
A B C
aaa -0.264438 -1.026059 -0.619500
bbb 0.927272 0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382 1.100491
这些解析器函数还有许多参数可以帮助你处理各种各样的异形文件格式。比如说,你可以用skiprows跳过文件的第一行、第三行和第四行:
In [23]: !cat examples/ex4.csv
# hey!
a,b,c,d,message
# just wanted to make things more difficult for you
# who reads CSV files with computers, anyway?
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
In [24]: pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])
Out[24]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
缺失值处理是文件解析任务中的一个重要组成部分。缺失数据经常是要么没有(空字符串),要么用某个标记值表示。默认情况下,pandas会用一组经常出现的标记值进行识别,比如NA及NULL:
In [25]: !cat examples/ex5.csv
something,a,b,c,d,message
one,1,2,3,4,NA
two,5,6,,8,world
three,9,10,11,12,foo
In [26]: result = pd.read_csv('examples/ex5.csv')
In [27]: result
Out[27]:
something a b c d message
0 one 1 2 3.0 4 NaN
1 two 5 6 NaN 8 world
2 three 9 10 11.0 12 foo
In [28]: pd.isnull(result)
Out[28]:
something a b c d message
0 False False False False False True
1 False False False True False False
2 False False False False False False
字典的各列可以使用不同的NA标记值:
In [31]: sentinels = {'message': ['foo', 'NA'], 'something': ['two']}
In [32]: pd.read_csv('examples/ex5.csv', na_values=sentinels)
Out[32]:
something a b c d message
0 one 1 2 3.0 4 NaN
1 NaN 5 6 NaN 8 world
2 three 9 10 11.0 12 NaN
下图列出了pandas.read_csv和pandas.read_table常用的选项。