1.读取文本文件:
将表格型数据读取为DataFrame对象是Pandas的重要特性。数据分析中最常用的文件格式为csv文件(逗号分隔的文件),因此使用pandas读取问价时最常用的函数主要是read_csv()
和read_table()
。
1.1 使用read_csv()
读取文件
import pandas as pd
df = pd.read_csv('./PM25.csv', encoding='gb18030')
print(df)
本次以2018年全年PM2.5超标城市前十名数据为例,数据如下:
城市 超标天数 超标月数 省份 分布区域
0 和田地区 177 5.900000 新疆 西部
1 喀什地区 163 5.433333 新疆 西部
2 石家庄 117 3.900000 河北 东部
3 阿克苏地区 113 3.766667 新疆 西部
4 临汾 110 3.666667 山西 中部
5 保定 109 3.633333 河北 东部
6 咸阳 107 3.566667 陕西 中部
7 安阳 104 3.466667 河南 中部
8 邢台 103 3.433333 河北 东部
1.2 使用read_table()
方法时需指定分隔符
针对csv或者其他固定格式的文件传递分隔符给sep
属性即可,如果分隔符不是固定的话,可以传递一个正则表达式。
df = pd.read_table('./PM25.csv', encoding='gb18030',sep=',')
1.3 读取不包含表头的文件
df = pd.read_csv('./PM25.csv',header=None,encoding='gb18030')
此时pandas会自动分配默认列名。
0 1 2
0 和田地区 177 5.900000 新疆 西部
1 喀什地区 163 5.433333 新疆 西部
2 石家庄 117 3.900000 河北 东部
3 阿克苏地区 113 3.766667 新疆 西部
4 临汾 110 3.666667 山西 中部
5 保定 109 3.633333 河北 东部
6 咸阳 107 3.566667 陕西 中部
7 安阳 104 3.466667 河南 中部
8 邢台 103 3.433333 河北 东部
如果问价不包含表头,读取时可以自己指定列名。
df = pd.read_csv('./PM25.csv',names=['列1','列2','列3'],encoding='gb18030')
print(df)
列1 列2 列3
0 和田地区 177 5.900000 新疆 西部
1 喀什地区 163 5.433333 新疆 西部
2 石家庄 117 3.900000 河北 东部
3 阿克苏地区 113 3.766667 新疆 西部
4 临汾 110 3.666667 山西 中部
5 保定 109 3.633333 河北 东部
6 咸阳 107 3.566667 陕西 中部
7 安阳 104 3.466667 河南 中部
8 邢台 103 3.433333 河北 东部
1.4 按指定列作为索引读取文件
加入此时要将省份列作为对象的索引,就需使用index_col
参数。
df = pd.read_csv('./PM25.csv',index_col='省份',encoding='gb18030')
print(df)
城市 超标天数 超标月数 分布区域
省份
新疆 和田地区 177 5.900000 西部
新疆 喀什地区 163 5.433333 西部
河北 石家庄 117 3.900000 东部
新疆 阿克苏地区 113 3.766667 西部
山西 临汾 110 3.666667 中部
河北 保定 109 3.633333 东部
陕西 咸阳 107 3.566667 中部
河南 安阳 104 3.466667 中部
河北 邢台 103 3.433333 东部
如果想要使用多列形成一个分层索引的话,只需将列序号或者列名的列表传递给index_col
参数。
df = pd.read_csv('./PM25.csv',index_col=['分布区域','省份'],encoding='gb18030')
1.5 读取文件跳过某行数据
此时使用到skiprows
参数,将需跳过的行数序号列表传递进去。
df = pd.read_csv('./PM25.csv',skiprows=[0,1,2,3],encoding='gb18030')
print(df)
阿克苏地区 113 3.766666667 新疆 西部
0 临汾 110 3.666667 山西 中部
1 保定 109 3.633333 河北 东部
2 咸阳 107 3.566667 陕西 中部
3 安阳 104 3.466667 河南 中部
4 邢台 103 3.433333 河北 东部
1.6 文件缺失值处理
使用isnull()
方法判断读取的文件中是否存在缺失值。
# 此时将之前使用的数据删除了一些数据,使得其存在缺失值
df = pd.read_csv('./PM25.csv',encoding='gb18030')
print(pd.isnull(df))
结果返回一个布尔型数据。
城市 超标天数 超标月数 省份 分布区域
0 False False False False False
1 False False False False True
2 False True False False False
3 False False False False False
4 False False False False False
5 False False False False True
6 False False False False False
7 False False False False False
8 False True False False False
1.7 read_csv()
和read_table()
的常用参数
参数 | 说明 |
---|---|
path | 指定文件位置 |
sep/delimiter | 指定分隔符序列或正则表达式 |
header | 列名行号,默认第一行为0 |
index_col | 用作结果中行索引的列名或列号 |
names | 指定结果的列名列表,与header=None一起使用 |
skiprows | 从文件开头开始,需要跳过的行数或行号列表 |
nrows | 从文件开头开始读入的行数 |
skip_footer | 忽略文件尾部的行数 |
encoding | 用于指定文本编码 |
thousands | 千位分隔符(,或.) |
更多参数可以前往官方文档查看。
2.将数据写入文本文件:
将数据写入文本文件最常用使用的是to_csv()
方法,该方法默认为逗号分隔,也可以通过sep
参数指定其他分隔符号。
df = pd.read_csv('./PM25.csv',encoding='gb18030')
df.to_csv('./PM25_new.csv',sep='|')
df_new = pd.read_csv('./PM25_new.csv')
print(df_new)
```
|城市|超标天数|超标月数|省份|分布区域
0 0|和田地区|177.0|5.9|新疆|西部
1 1|喀什地区|163.0|5.433333332999999|新疆|
2 2|石家庄||3.9|河北|东部
3 3|阿克苏地区|113.0|3.766666667|新疆|西部
4 4|临汾|110.0|3.666666667|山西|中部
5 5|保定|109.0|3.633333333|河北|
6 6|咸阳|107.0|3.566666667|陕西|中部
7 7|安阳|104.0|3.4666666669999997|河南|中部
8 8|邢台||3.433333333|河北|东部
默认情况下,行和列的标签都会被写入文件,如需禁止写入可以通过设置index=False
和header=False
完成。
df.to_csv('./PM25_new.csv',sep='|',index=False,header=False)
也可以仅写入数据的子集,并且按照设定的顺序写入。
df.to_csv('./PM25_new.csv',columns=['城市','超标天数'])
3.excel数据的读写操作:
虽说日常常用的数据格式为csv,不过pandas也支持对excel文件的读写操作(ExcelFile类
或者read_excel()
方法)。
3.1 读取excel文件
使用ExcelFile
生成一个实例,然后通过read_excel()
方法读取到DataFrame中。
xlsx = pd.ExcelFile('./2018PM25.xlsx')
xlsx_data = pd.read_excel(xlsx,'Sheet1')
print(xlsx_data)
也可以通过更简洁的read_excel()
方法读取,如果要读取的excel文件含有多个表,在读取时需要将表名传入。
xlsx = pd.read_excel('./2018PM25.xlsx','Sheet1')
3.2 写入excel文件
如需将pandas数据写入excel中,也可以使用ExcelWriter
先生成一个实例,然后再使用to_excel()
方法将数据写入。
writer = pd.ExcelWriter('./2018PM25_new.xlsx')
df.to_excel(writer,'sheet1')
writer.save()
同样,也可以直接使用to_excel()
方法。
df.to_excel('./2018PM25_new.xlsx')
4.JSON数据的读写操作:
- 使用
json.loads()
方法,可以将json数据转为换为python形式。
这里以百度地图地点检索api获取的json数据为例。
import requests
import json
url = 'http://api.map.baidu.com/place/v2/search?query=%E9%93%B6%E8%A1%8C&bounds=39.915,116.404,39.975,116.414&output=json&ak=ak值'
res = requests.get(url).text
result = json.loads(res)
print(result)
{'status': 0, 'message': 'ok', 'results': [{'name': '中国民生银行(安定门支行)', 'location': {'lat': 39.971315, 'lng': 116.413576}, 'address': '北京市朝阳区安定门外大街1号', 'province': '北京市', 'city': '北京市', 'area': '朝阳区', 'street_id': '53cebd509fbca9612a02e14c', 'telephone': '(010)58295666', 'detail': 1, 'uid': '53cebd509fbca9612a02e14c'}, {'name': '北京银行(中轴路支行)', 'location': {'lat': 39.957457, 'lng': 116.40428}, 'address': '北京市东城区安德路16号(洲际大厦首层)', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': '33ddf832c2d7244952e5c51e', 'telephone': '95526', 'detail': 1, 'uid': '33ddf832c2d7244952e5c51e'}, {'name': '交通银行(北京和平里支行)', 'location': {'lat': 39.968787, 'lng': 116.410049}, 'address': '北京市朝阳区外馆东街51号', 'province': '北京市', 'city': '北京市', 'area': '朝阳区', 'street_id': 'e56bf5e3064b7b440782c2ff', 'telephone': '(010)64408115', 'detail': 1, 'uid': 'e56bf5e3064b7b440782c2ff'}, {'name': '中国进出口银行(北京分行)', 'location': {'lat': 39.934898, 'lng': 116.411758}, 'address': '北京市东城区北河沿大街77号', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': '6334ddeb6a99710bfea77863', 'telephone': '(010)64099688', 'detail': 1, 'uid': '6334ddeb6a99710bfea77863'}, {'name': '中国工商银行(北京地坛支行)', 'location': {'lat': 39.965762, 'lng': 116.412735}, 'address': '北京市东城区安外大街9号', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': '50f7d1461f0208c472210bff', 'telephone': '(010)84122100', 'detail': 1, 'uid': '50f7d1461f0208c472210bff'}, {'name': '北京银行(沙滩支行)', 'location': {'lat': 39.929203, 'lng': 116.412428}, 'address': '北京市东城区北河沿大街95号6层97号一层', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': '9ca676f2a814373a43e19275', 'telephone': '(010)65220219', 'detail': 1, 'uid': '9ca676f2a814373a43e19275'}, {'name': '中国银行(安定门外支行)', 'location': {'lat': 39.958051, 'lng': 116.413457}, 'address': '北京市东城区安定门外大街191号', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': 'f4460918f2b3296ab11e36ff', 'telephone': '(010)64400221', 'detail': 1, 'uid': 'f4460918f2b3296ab11e36ff'}, {'name': '中国工商银行(北京和平里支行安德公路储蓄所)', 'location': {'lat': 39.958072, 'lng': 116.407072}, 'address': '北京市东城区安德路47-5号', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': 'cc788fde07292f8a88fc06ff', 'telephone': '(010)84124439,(010)84124438', 'detail': 1, 'uid': 'cc788fde07292f8a88fc06ff'}, {'name': '中国工商银行(北京东华门支行)', 'location': {'lat': 39.921373, 'lng': 116.411402}, 'address': '东华门大街20号', 'province': '北京市', 'city': '北京市', 'area': '东城区', 'street_id': 'dbf4d6eee23caa546ea3cc87', 'telephone': '(010)65125921', 'detail': 1, 'uid': 'dbf4d6eee23caa546ea3cc87'}, {'name': '中国工商银行(北京和平北路东口支行)', 'location': {'lat': 39.968629, 'lng': 116.410245}, 'address': '北京市朝阳区外馆东街51号凯景铭座一层', 'province': '北京市', 'city': '北京市', 'area': '朝阳区', 'telephone': '(010)84123118', 'detail': 1, 'uid': '4482d48423f9a3b33fe23125'}]}
- 使用
json.dump()
方法可以将python对象转换为json数据格式
json_result = json.dump(result)
- 将json数据转换为Pandas数据格式
df = pd.DataFrame(result['results'],columns=['name','address'])
print(df)
name address
0 中国民生银行(安定门支行) 北京市朝阳区安定门外大街1号
1 北京银行(中轴路支行) 北京市东城区安德路16号(洲际大厦首层)
2 交通银行(北京和平里支行) 北京市朝阳区外馆东街51号
3 中国进出口银行(北京分行) 北京市东城区北河沿大街77号
4 中国工商银行(北京地坛支行) 北京市东城区安外大街9号
5 北京银行(沙滩支行) 北京市东城区北河沿大街95号6层97号一层
6 中国银行(安定门外支行) 北京市东城区安定门外大街191号
7 中国工商银行(北京和平里支行安德公路储蓄所) 北京市东城区安德路47-5号
8 中国工商银行(北京东华门支行) 东华门大街20号
9 中国工商银行(北京和平北路东口支行) 北京市朝阳区外馆东街51号凯景铭座一层
另外,read_json()
方法可以自动将json数据按照指定次序转换为Pandas数据格式。
df = pd.read_json(res)
- 将pandas数据存为json数据
使用to_json()
方法。
df.to_json()
5.二进制数据格式读写:
5.1 pickle格式
使用python内建的pickle
序列化模块进行二进制格式操作是存储数据做高效、最方便的方式之一。
使用to_pickle()
方法可以将数据以pickle格式写入硬盘。
读取时,直接使用read_pickle()
方法读取。
需注意的是,因为pickle很难确保格式的长期有效性(今天被pickle化的对象可能回头会因为库的新版本而无法反序列化),因此仅被推荐作为短期的存储格式。
5.2 HDF5格式
HDF5格式是以C库的形式提供,并且具有许多其他语言的接口。HDF5中的HDF代表分层数据格式,每个HDF5文件可以存储多个数据集并且支持元数据。与更简单的格式相比,HDF5支持多种压缩模式的即时压缩,使得重复模式的数据可以更高效的存储。
Pandas提供了一个高阶的接口(HDFStore类),可以简化数据的存储为HDF5格式。HDFStore类可以想字典一样进行操作。
import pandas as pd
import numpy as np
df = pd.DataFrame({'a':np.random.randn(50)})
store = pd.HDFStore('./data.h5')
store['obj'] = df
store['obj_col'] = df['a']
print(store)
<class 'pandas.io.pytables.HDFStore'>
Closing remaining open files:./data.h5...done
File path: ./data.h5
包含在HDF5文件中的对象可以使用字典型API进行检索。
print(store['obj'])
a
Closing remaining open files:./data.h5...done
0 -0.640117
1 -0.156205
2 0.524390
3 -1.539300
4 0.793609
.......
6.XML和HTML格式数据的操作:
XML和HTML格式数据主要来自网络爬取过程,具体操作将在Python网络爬虫部分进行介绍。
Reference:
《Python for Data Analysis:Data Wrangling with Pandas,Numpy,and IPython》