文件读取

阅读: 6093     评论:2

前面的例子中,我们都是通过手动输入数据来生成Series和DataFrame对象。在实际工作中,这显然是不可能的。大多数时候,我们都要与外部进行数据交换,输入和输出。有很多的工具可以帮助我们读取和写入各种格式的数据,但是Pandas自己提供的读写工具更方便更适合。

数据交换主要有以下几种类型:

  • 读取文本文件或磁盘上的其它高效文件格式
  • 与数据库交互
  • 与网络资源,比如Web API进行交互

1. 文本格式数据的读写

在Pandas的使用场景中,最多的是将表格型的数据读取为DataFrame对象。实现这一功能的函数有很多,最常用的是read_csvread_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_csvread_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 定义千位分隔符,例如逗号或者圆点

 统计和汇总 分块读取 

评论总数: 2


点击登录后方可评论

还有个关键的参数没提到:usecols,读取指定的列。



第一个表格第一行第一个开头是不是少写了"rea"三个字母?