前面的例子中,我们都是通过手动输入数据来生成Series和DataFrame对象。在实际工作中,这显然是不可能的。大多数时候,我们都要与外部进行数据交换,输入和输出。有很多的工具可以帮助我们读取和写入各种格式的数据,但是Pandas自己提供的读写工具更方便更适合。
数据交换主要有以下几种类型:
在Pandas的使用场景中,最多的是将表格型的数据读取为DataFrame对象。实现这一功能的函数有很多,最常用的是read_csv
和read_table
。
下表列出了pandas主要的读写函数:
函数 | 说明 |
---|---|
d_csv | 读取默认以逗号作为分隔符的文件 |
read_table | 读取默认以制表符分隔的文件 |
read_fwf | 从特定宽度格式的文件中读取数据(无分隔符) |
read_clipboard |
read_table 的剪贴板版本 |
read_excel | 从EXCEL的XLS或者XLSX文件中读取数据 |
read_hdf | 读取用pandas存储的HDF5文件 |
read_html | 从HTML文件中读取所有表格数据 |
read_json | 从JSON字符串中读取数据 |
read_msgpack | 读取MessagePack格式存储的任意对象 |
read_pickle | 读取以Python Pickle格式存储的对象 |
read_sas | 读取SAS系统中定制存储格式的数据集 |
read_sql | 将SQL查询的结果读取出来 |
read_stata | 读取stata格式的数据集 |
read_feather | 读取Feather二进制格式 |
Pandas不但有这么多的读取函数,每个函数还有大量的可设置参数。比如read_csv到目前就有超过50个参数。这些函数和参数是如此的复杂,很难有人能够将它们全部记住,所以当你在读取文件时遇到了困难,请前往官方文档,那里的一些示例可能对你有帮助。
让我们来看看一些具体的例子,首先有这么一个文件:
# ex1.csv a,b,c,d,message 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo
可以使用read_csv方法读取它,默认第一行为列索引,自动生成了行索引:
In [14]: df = pd.read_csv('d:/ex1.csv') In [15]: df Out[15]: 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 [17]: pd.read_table('d:/ex1.csv',sep=',') Out[17]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
对于不包含表头行的文件,比如下面的ex2,要么使用默认列名,要么我们指定列名:
1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo
注意指定列名用的参数名是names,不是columns:
In [18]: pd.read_csv('d:/ex2.csv',header=None) # 使用默认列名 Out[18]: 0 1 2 3 4 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo In [19]: pd.read_csv('d:/ex2.csv', names=['a','b','c','d','message']) # 自定义 Out[19]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
如果你想将上面的message列当作DataFrame的行索引,可以将它传递给参数index_col:
# 注意其中的names依然必须包含message字符串,否则会弹出KeyError In [20]: pd.read_csv('d:/ex2.csv', names=['a','b','c','d','message'],index_col='message') Out[20]: a b c d message hello 1 2 3 4 world 5 6 7 8 foo 9 10 11 12
如果想读取成分层索引,则需要为index_col参数传入一个包含列序号或列名的列表:
# csv_mindex.csv key1,key2,value1,value2 one,a,1,2 one,b,3,4 one,c,5,6 one,d,7,8 two,a,9,10 two,b,11,12 two,c,13,14 two,d,15,16
分层索引类似多级索引,后面会介绍。
In [22]: df = pd.read_csv('d:/csv_mindex.csv', index_col=['key1','key2']) In [23]: df Out[23]: value1 value2 key1 key2 one a 1 2 b 3 4 c 5 6 d 7 8 two a 9 10 b 11 12 c 13 14 d 15 16
对于一些更复杂,或者说更不规整的文件,比如分隔符不固定的情况,需要有更多的处理技巧,比如下面这个文件,以不同数量的空格分隔:
# ex3.txt 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
这时候需要传入一个正则表达式作为分隔符参数:
In [25]: result = pd.read_table('d:/ex3.txt', sep='\s+') In [26]: result Out[26]: 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
上面的正则表达式是\s+
。并且由于列名比数据的列数少一个,系统自动推断第一列应当作为行索引。
大多数读取函数都带有很多帮助我们处理各种异常情况的参数,比如可以使用skiprows来跳过数据中的指定行.
原始数据:
# 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
我们需要跳过无用的第1、3、4行废话:
In [27]: pd.read_csv('d:/ex4.csv', skiprows=[0,2,3]) Out[27]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
缺失值的处理是读取数据时非常重要的部分。通常情况下,缺失值要么不显示,直接空着,要么用一些标识值表示,比如NA或NULL。
看下面的数据,注意第三行的6和8之间有个空的:
something,a,b,c,d,message one,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo
read_csv
会将缺失值自动读成NaN:
In [30]: result = pd.read_csv('d:/ex5.csv') In [31]: result Out[31]: 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 [32]: pd.isnull(result) Out[32]: 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_values
参数,将某些值也当作缺失值来看待,比如下面我们将3.0也当作缺失值对待:
In [40]: result = pd.read_csv('d:/ex5.csv',na_values=[3.0]) In [41]: result Out[41]: something a b c d message 0 one 1 2 NaN 4 NaN 1 two 5 6 NaN 8 world 2 three 9 10 11.0 12 foo
甚至可以对不同的列,指定不同的缺失值标识:
In [42]: f = {'message':['foo','NA'],'something':['two']} In [43]: result = pd.read_csv('d:/ex5.csv',na_values=f) In [44]: result Out[44]: 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
下表列出了read_csv
和read_table
函数的一些常用参数:
参数 | 说明 |
---|---|
path | 文件路径 |
sep | 指定分隔符或正则表达式 |
header | 用作列名的行号 |
index_col | 用作行索引的列名或列号 |
names | 结果的列名列表 |
skiprows | 从起始处,需要跳过的行 |
na_values | 需要用NaN替换的值 |
comment | 在行结尾处分隔注释的字符 |
parse_dates | 尝试将数据解析为datetime,默认是False |
keep_date_col |
如果连接列到解析日期上,保留被连接的列,默认False |
converters | 包含列名称映射到函数的字典 |
dayfirst | 解析非明确日期时,按国际格式处理 |
date_parser | 用于解析日期的函数 |
nrows | 从文件开头处读入的行数 |
iterator | 返回一个TextParser对象,用于零散地读入文件 |
chunksize | 用于迭代的块大小 |
skip_footer | 忽略文件尾部的行数 |
verbose | 打印各种解析器输出的信息 |
encoding | 文本编码,比如UTF-8 |
thousands | 定义千位分隔符,例如逗号或者圆点 |
还有个关键的参数没提到:usecols,读取指定的列。
第一个表格第一行第一个开头是不是少写了"rea"三个字母?