首页Python10.文本格式数据的读写

10.文本格式数据的读写

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=Falseheader=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》

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments