输入输出通常可以划分为几个大类:读取文本文件和其他更高效的磁盘存储格式,加载数据库中的数据,利用Web API操作网络资源。
读写文本格式的数据
pandas
提供了一些用于将表格型数据读取为DataFrame对象的函数。read_csv
和read_table
是最为常用的。
这些函数的选项可以划分为以下几个大类:
- 索引:将一个或多个列当做返回的DataFrame处理,以及是否从文件、用户获取列名。
- 类型推断和数据转换:包括用户定义值的转换、和自定义的缺失值标记列表等。
- 日期解析:包括组合功能,比如将分散在多个列中的日期时间信息组合成结果中的单个列。
- 迭代:支持对大文件进行逐块迭代。
- 不规整数据问题:跳过一些行、页脚、注释或其他一些不重要的东西(比如由成千上万个逗号隔开的数值数据)。
- 其中一些函数,比如
pandas.read_csv
,有类型推断功能,不需要指定列的类型到底是数值、整数、布尔值,还是字符串。其它的数据格式,如HDF5、Feather和msgpack,会在格式中存储数据类型。 - 读入无标题行的文件时,可以让pandas为其分配默认的列名,也可以自己定义列名:
pd.read_csv('examples/ex2.csv', header=None)
pd.read_csv('examples/ex2.csv', names=['a','b','c','d','message'])
pd.read_csv('examples/ex2.csv', names=names, index_col='message') # 指定message列为索引
- 对于非固定的分隔符分隔字段的文件,可以使用正则表达式作为read_table的分隔符,如:
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[21]: result = pd.read_table('examples/ex3.txt', sep='\s+') # \s+表示任意数量空格
# 这里,由于列名比数据行的数量少,所以read_table推断第一列应该是DataFrame的索引。
skiprows
可以用于跳过指定行:pd.read_csv('examples/ex4.csv', skiprows=[0,2,3])
pandas
会用NA
及NULL
来标记数据中的缺失值。- 数据的各列可以使用不同的NA标记值:
pd.read_csv('examples/ex5.csv', na_values={'message':['foo','NA'],'something':['two']})
- 如果只想读取几行(避免读取整个文件),通过nrows进行指定即可:
pd.read_csv('examples/ex6.csv', nrows=5)
要逐块读取文件,可以指定chunksize(行数):
chunker = pd.read_csv('ch06/ex6.csv', chunksize=1000) # 返回TextParser对象
for piece in chunker:
......
- DataFrame和Series都可输出为csv文件:
data.to_csv('examples/out.csv') # 默认逗号分隔,也可通过sep='\t'设定为其他符号
data.to_csv('examples/out.csv', na_rep='NULL') # 将缺失值设定为指定值
data.to_csv('examples/out.csv', index=False, header=False) # 不输出行和列的标签
- json数据:
pandas.read_json
可以自动将特别格式的JSON数据集转换为Series
或DataFrame
data = pd.read_json('examples/example.json') # 默认选项假设JSON数组中的每个对象是表格中的一行
print(data.to_json()) # 将数据从pandas输出到JSON
- XML和HTML:Web信息收集。Python有许多可以读写常见的HTML和XML格式数据的库,包括lxml、Beautiful Soup和html5lib。lxml的速度比较快,但其它的库处理有误的HTML或XML文件更好。
pandas.read_html
可以使用lxml和Beautiful Soup自动将HTML文件中的表格解析为DataFrame
对象。 - XML(Extensible Markup Language)是另一种常见的支持分层、嵌套数据以及元数据的结构化数据格式。XML和HTML的结构很相似,但XML更为通用。
from lxml import objectify
path ='datasets/mta_perf/Performance_MNR.xml'
parsed = objectify.parse(open(path)) # 解析文件
root = parsed.getroot() # 得到该XML文件的根节点的引用
from io import StringIO
tag ='<a href="http://www.google.com">Google</a>'
root = objectify.parse(StringIO(tag)).getroot()
In[85]: root.get('href')
Out[85]:'http://www.google.com'
In[86]: root.text
Out[86]:'Google'
二进制数据格式
- 实现数据的高效二进制格式存储最简单的办法之一是使用Python内置的
pickle
序列化。pandas
对象都有一个用于将数据以pickle格式保存到磁盘上的to_pickle
方法:
frame = pd.read_csv('examples/ex1.csv')
frame.to_pickle('examples/frame_pickle')
- 可以通过pickle直接读取被pickle化的数据,或是使用更为方便的
pandas.read_pickle
:pd.read_pickle('examples/frame_pickle')
- 注意:pickle仅建议用于短期存储格式。其原因是很难保证该格式永远是稳定的;今天pickle的对象可能无法被后续版本的库unpickle出来。
- pandas内置支持两个二进制数据格式:HDF5和MessagePack。
pandas或NumPy数据的其它存储格式有:
- bcolz:一种可压缩的列存储二进制格式,基于Blosc压缩库。
- Feather:我与R语言社区的Hadley Wickham设计的一种跨语言的列存储文件格式。Feather使用了Apache Arrow的列式内存格式。
- HDF5是一种存储大规模科学数组数据的非常好的文件格式。它可以被作为C标准库,带有许多语言的接口,如Java、Python和MATLAB等。HDF指层次型数据格式(hierarchical data format),每个HDF5文件都含有一个文件系统式的节点结构,它使你能够存储多个数据集并支持元数据。与其他简单格式相比,HDF5支持多种压缩器的即时压缩,还能更高效地存储重复模式数据。对于那些非常大的无法直接放入内存的数据集,HDF5就是不错的选择,因为它可以高效地分块读写。
虽然可以用PyTables
或h5py
库直接访问HDF5文件,pandas
提供了更为高级的接口,可以简化存储Series
和DataFrame
对象。
frame = pd.DataFrame({'a': np.random.randn(100)})
store = pd.HDFStore('mydata.h5')
store['obj1'] = frame
store['obj1_col'] = frame['a']
store['obj1'] # HDF5文件中的对象可以通过与字典一样的API进行获取
store.put('obj2', frame, format='table') # table格式支持使用特殊语法进行查询操作
store.select('obj2', where=['index >= 10 and index <= 15'])
pd.read_hdf('mydata.h5', 'obj3', where=['index < 5'])
- Excel:
pandas
的ExcelFile
类或pandas.read_excel
函数分别使用扩展包xlrd
和openpyxl
读取XLS
和XLSX
文件。
如果要读取一个文件中的多个表单,创建ExcelFile会更快
xlsx = pd.ExcelFile('examples/ex1.xlsx')
frame = pd.read_excel(xlsx, 'Sheet1')
frame = pd.read_excel('examples/ex1.xlsx', 'Sheet1')
如果要将pandas
数据写入为Excel
格式,你必须首先创建一个ExcelWriter
,然后使用pandas
对象的to_excel
方法将数据写入到其中:
In [108]: writer = pd.ExcelWriter('examples/ex2.xlsx')
In [109]: frame.to_excel(writer, 'Sheet1')
In [110]: writer.save()
你还可以不使用ExcelWriter
,而是传递文件的路径到to_excel:
In [111]: frame.to_excel('examples/ex2.xlsx')
数据库交互
将数据从SQL
加载到DataFrame
的过程很简单,此外pandas
还有一些能够简化该过程的函数。
In [121]: import sqlite3
In [122]: query = """
.....: CREATE TABLE test
.....: (a VARCHAR(20), b VARCHAR(20),
.....: c REAL, d INTEGER
.....: );"""
In [123]: con = sqlite3.connect('mydata.sqlite')
In [124]: con.execute(query)
In [125]: con.commit()
# 插入数据
In [126]: data = [('Atlanta', 'Georgia', 1.25, 6),
.....: ('Tallahassee', 'Florida', 2.6, 3),
.....: ('Sacramento', 'California', 1.7, 5)]
In [127]: stmt = "INSERT INTO test VALUES(?, ?, ?, ?)"
In [128]: con.executemany(stmt, data)
# 返回一个元组列表
In [130]: cursor = con.execute('select * from test')
In [131]: rows = cursor.fetchall()
In [132]: rows
Out[132]:
[('Atlanta', 'Georgia', 1.25, 6),
('Tallahassee', 'Florida', 2.6, 3),
('Sacramento', 'California', 1.7, 5)]
SQLAlchemy
项目是一个流行的Python SQL
工具,它抽象出了SQL
数据库中的许多常见差异。pandas
有一个read_sql
函数,可以让你轻松的从SQLAlchemy
连接读取数据。这里,我们用SQLAlchemy
连接SQLite
数据库,并从之前创建的表读取数据:
In [135]: import sqlalchemy as sqla
In [136]: db = sqla.create_engine('sqlite:///mydata.sqlite')
In [137]: pd.read_sql('select * from test', db)
Out[137]:
a b c d
0 Atlanta Georgia 1.25 6
1 Tallahassee Florida 2.60 3
2 Sacramento California 1.70 5