《利用Python进行数据分析》Chapter 6

本章主要介绍pandas对数据分输入和输出。通常有以下几种类型:读取文本文件及硬盘上其他更高效的格式文件、从数据库载入数据、与网络资源进行交互(比如Web API)。

1. 文本格式数据的读写

使用最多的函数:
read_csv : 从文件、URL或文件型对象读取分隔好的数据,默认分隔符是逗号
read_table: 从文件、URL或文件型对象读取分隔好的数据,默认分隔符是制表符(’\t’)
read_excel: 从Excel的XLS或XLSX文件中读取表格
read_html: 从HTML文件中读取所有表格数据
read_json: 从JSON字符串中读取数据
read_sql: 将SQL查询的结果(使用SQLAlchemy)读取为pandas的DtatFrame

! type pydata-book-2nd-edition\examples\ex1.csv # 使用type命令来打印文件的原始内容
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
df = pd.read_csv('pydata-book-2nd-edition\examples\ex1.csv')
df
	a	b	c	d	message
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo
pd.read_table("pydata-book-2nd-edition\examples\ex1.csv", sep=',') #指定分隔符
	a	b	c	d	message
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo
1.1 读取时的一些选项

a. 有些文件并不包含表头行,可以指定pandas的默认列名,也可以指定列名

! type pydata-book-2nd-edition\examples\ex2.csv
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
pd.read_csv('pydata-book-2nd-edition\examples\ex2.csv') # 默认将第一行作为列名
	1	2	3	4	hello
0	5	6	7	8	world
1	9	10	11	12	foo
pd.read_csv("pydata-book-2nd-edition\examples\ex2.csv", header=None) # 使用pandas默认列名
	0	1	2	3	4
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo
pd.read_csv('pydata-book-2nd-edition\examples\ex2.csv', names=['a', 'b', 'c', 'd', 'message'])
	a	b	c	d	message
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo
pd.read_csv('pydata-book-2nd-edition\examples\ex2.csv', names=['a', 'b', 'c', 'd', 'message'], 		
			index_col='message')
			
		a	b	c	d
message				
hello	1	2	3	4
world	5	6	7	8
foo	9	10	11	12

b. 可以从多个列中形成一个分层索引

! type pydata-book-2nd-edition\examples\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

pd.read_csv('pydata-book-2nd-edition\examples\csv_mindex.csv', index_col=['key1', 'key2'])
				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

c. 字段以多种不同数量的空格分开时,可以向分隔符参数传入正则表达式:

list(open('pydata-book-2nd-edition\examples\ex3.txt'))
['            A         B         C\n',
 'aaa -0.264438 -1.026059 -0.619500\n',
 'bbb  0.927272  0.302904 -0.032399\n',
 'ccc -0.264273 -0.386314 -0.217601\n',
 'ddd -0.871858 -0.348382  1.100491\n']
pd.read_table('pydata-book-2nd-edition\examples\ex3.txt', sep='\s+') 
		A			B			C    #列名数量比数据的列数少一个,read_table推断第一列作为索引
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

d. 利用参数帮助处理发生异常的文件格式,常用:path / sep / header / index_col / names / skiprows / na_values

! type pydata-book-2nd-edition\examples\ex4.csv
# 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

pd.read_csv('pydata-book-2nd-edition\examples\ex4.csv', skiprows=[0, 2, 3]) # skiprow跳过指定行
	a	b	c	d	message
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo

na_values 选项可以传入一个列表或一组字符串来处理缺失值,指定需要用NA替换的值序列

pd.read_csv('pydata-book-2nd-edition\examples\ex5.csv')
	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
sentinels = {
     'message': ['foo', 'NA'], 'something': ['two']}
pd.read_csv('pydata-book-2nd-edition\examples\ex5.csv', na_values=sentinels)
	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
1.2 分块读入文件

处理大型文件或找出正确的参数集来正确处理大文件时,可以读入文件的一个小片段或者按小块遍历文件。
a. nrows 只读取一小部分行(避免读取整个文件):

pd.options.display.max_rows = 10 # pandas显示设置
pd.read_csv('pydata-book-2nd-edition\examples\ex6.csv')
		one			two			three		four	key
0	0.467976	-0.038649	-0.295344	-1.824726	L
1	-0.358893	1.404453	0.704965	-0.200638	B
2	-0.501840	0.659254	-0.421691	-0.057688	G
3	0.204886	1.074134	1.388361	-0.982404	R
4	0.354628	-0.133116	0.283763	-0.837063	Q
...	...	...	...	...	...
9995	2.311896	-0.417070	-1.409599	-0.515821	L
9996	-0.479893	-0.650419	0.745152	-0.646038	E
9997	0.523331	0.787112	0.486066	1.093156	K
9998	-0.362559	0.598894	-1.843201	0.887292	G
9999	-0.096376	-1.012999	-0.657431	-0.573315	0
10000 rows × 5 columns
pd.read_csv('pydata-book-2nd-edition\examples\ex6.csv', nrows=5) #读取5行
		one			two			three		four	key
0	0.467976	-0.038649	-0.295344	-1.824726	L
1	-0.358893	1.404453	0.704965	-0.200638	B
2	-0.501840	0.659254	-0.421691	-0.057688	G
3	0.204886	1.074134	1.388361	-0.982404	R
4	0.354628	-0.133116	0.283763	-0.837063	Q

b. chunksize 分块读入文件并遍历:

chunker = pd.read_csv('pydata-book-2nd-edition\examples\ex6.csv', chunksize=1000)
type(chunker)
pandas.io.parsers.TextFileReader

tot = pd.Series([ ])
for piece in chunker:
    tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.sort_values(ascending=False)
tot[:10]
E    368.0
X    364.0
L    346.0
O    343.0
Q    340.0
M    338.0
J    337.0
F    335.0
K    334.0
H    330.0
dtype: float64

TextParser 还具有get_chunk方法,可以按照任意大小读取数据块。

1.3 将数据写入文本格式
data.to_csv('out.csv') # 默认为逗号分隔的文件
,something,a,b,c,d,message
0,one,1,2,3.0,4,
1,two,5,6,,8,world
2,three,9,10,11.0,12,foo

其他的分隔符也是可以的

import sys
data.to_csv(sys.stdout, sep='|')
|something|a|b|c|d|message
0|one|1|2|3.0|4|
1|two|5|6||8|world
2|three|9|10|11.0|12|foo

缺失值在输出时以空字符串出现,也可以设定其他标识值:

data.to_csv(sys.stdout, na_rep='NULL')
,something,a,b,c,d,message
0,one,1,2,3.0,4,NULL
1,two,5,6,NULL,8,world
2,three,9,10,11.0,12,foo
data.to_csv(sys.stdout, index=False, header=False) # 默认行列标签都会写入,也可以禁止写入
one,1,2,3.0,4,
two,5,6,,8,world
three,9,10,11.0,12,foo
data.to_csv(sys.stdout, index=False, columns=['a', 'b', 'c']) # 可以指定选取特定的列来写入
a,b,c
1,2,3.0
5,6,
9,10,11.0
1.4 使用分隔格式

对于任何带有单字符分隔符的文件,将任一打开的文件或文件型对象传给csv.reader,遍历reader会产生元组,可以根据需要生成特定格式的数据文件。

import csv
with open('pydata-book-2nd-edition/examples/ex7.csv') as f:
    lines = list(csv.reader(f))
header, values = lines[0], lines[1:]
data_dict = {
     h: v for h, v in zip(header, zip(*values))}
data_dict
{
     'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}
1.5 JSON数据

JSON 已经成为Web浏览器和其他应用间通过HTTP请求发送数据的标准格式,是一种比CSV等表格文本格式更为自由的数据形式。
JSON 对象中的所有键都必须是字符串。

obj = """
{"name": "Wes",
 "places_lived": ["United States", "Spain", "Germany"],
 "pet": null,
 "siblings": [{"name": "Scott", "age": 30, "pets": ["Zeus", "Zuko"]},
              {"name": "Katie", "age": 38,
               "pets": ["Sixes", "Stache", "Cisco"]}]
}
"""
result = json.loads(obj) # JSON字符串转化为Python形式
result
{
     'name': 'Wes',
 'places_lived': ['United States', 'Spain', 'Germany'],
 'pet': None,
 'siblings': [{
     'name': 'Scott', 'age': 30, 'pets': ['Zeus', 'Zuko']},
  {
     'name': 'Katie', 'age': 38, 'pets': ['Sixes', 'Stache', 'Cisco']}]}
siblings = pd.DataFrame(result["siblings"], columns=['name', 'age', 'pets'])
siblings
	name	age	pets
0	Scott	30	[Zeus, Zuko]
1	Katie	38	[Sixes, Stache, Cisco]
asjson = json.dumps(result) # 将Python对象转换回JSON

read_json可以自动将JSON对象按照次序转换为Series或DataFrame。

! type example.json
[{
     "a": 1, "b": 2, "c": 3},
 {
     "a": 4, "b": 5, "c": 6},
 {
     "a": 7, "b": 8, "c": 9}]
data = pd.read_json('example.json') # 默认选项假设JSON数组中的每个对象是表里的一行
	a	b	c
0	1	2	3
1	4	5	6
2	7	8	9

to_json 方法可以将pandas数据导出为JSON

print(data.to_json())
{
     "a":{
     "0":1,"1":4,"2":7},"b":{
     "0":2,"1":5,"2":8},"c":{
     "0":3,"1":6,"2":9}}
print(data.to_json(orient='records')) # 将每一行转换为一个字典,形成一个字典列表
[{
     "a":1,"b":2,"c":3},{
     "a":4,"b":5,"c":6},{
     "a":7,"b":8,"c":9}]
1.6 XML和HTML:网络抓取

Python 有很多可以对HTML和XML格式进行读取、写入数据的库,例如lxml、Beautiful Soup 和 html5lib
lxml 相对更快,但其他的库可以更好的处理异常的HTML或XML文件。
a. read_html 函数将HTML中的表自动解析为 DataFrame 对象
b. lxml.objectify 解析 XML

2. 二进制格式

pickle 序列化模块可以进行二进制格式操作,是存储数据(称作序列化)最高效、方便的方式之一。

frame = pd.read_csv('pydata-book-2nd-edition/examples/ex1.csv')
frame
	a	b	c	d	message
0	1	2	3	4	hello
1	5	6	7	8	world
2	9	10	11	12	foo
frame.to_pickle('pydata-book-2nd-edition/examples/frame_pickle')

pandas 内建支持其他两个二进制格式:HDF5 和 MessagePack。

a. HDF5 格式
HDF5 用于存储大量的科学数组数据,HDF代表分层数据格式,每个HDF5文件可以存储多个数据集并且支持元数据。适用于处理不适合在内存中存储的超大型数据,可以使你高效读写大型数组的一小块。
HDF5 并不是数据库,是一种适合一次写入多次读取的数据集。

b. 读取Excel文件
pandas支持通过ExcelFile类或read_excel函数来读取excel文件中的表格型数据,需要安装xlrd和openyxl工具。

xlsx = pd.ExcelFile('pydata-book-2nd-edition/examples/ex1.xlsx') # 生成ExcelFile更快
pd.read_excel(xlsx, "Sheet1")
   Unnamed: 0	a	b	c	d	message
0			0	1	2	3	4	hello
1			1	5	6	7	8	world
2			2	9	10	11	12	foo
frame = pd.read_excel('pydata-book-2nd-edition/examples/ex1.xlsx', "Sheet1")
frame
   Unnamed: 0	a	b	c	d	message
0			0	1	2	3	4	hello
1			1	5	6	7	8	world
2			2	9	10	11	12	foo

如需将pandas数据写入到excel文件中,必须先生成一个ExcelWriter,然后使用to_excel方法:

writer = pd.ExcelWriter('pydata-book-2nd-edition/examples/ex2.xlsx')
frame.to_excel(writer, "Sheet1")
writer.save()

也可以将文件路径传给to_excel,避免直接调用ExcelWriter:

frame.to_excel('pydata-book-2nd-edition/examples/ex2.xlsx')
3. 与Web API交互

很多网站都有公开API,通过JSON或其他格式提供数据服务,使用requests包发送一个HTTP GET请求,将返回一个包含解析为本地Python对象的JSON字典:

import requests
url = 'https://api.github.com/repos/pandas-dev/pandas/issues'
resp = requests.get(url) #  get请求
data = resp.json() # response对象的json方法
pd.DataFrame(data, columns=['number', 'title', 'labels', 'state'])
4. 与数据库交互

当从数据库的表中选择数据时,大部分Python的SQL驱动返回的是元组的列表。
pandas的read_sql函数允许你从通用的SQLAlchemy连接中轻松地读取数据。

import sqlite3
query = """
CREATE TABLE test
(a VARCHAR(20), b VARCHAR(20),
 c REAL,        d INTEGER
);"""
con = sqlite3.connect('mydata.sqlite')
con.execute(query)
con.commit()

data = [('Atlanta', 'Georgia', 1.25, 6),
        ('Tallahassee', 'Florida', 2.6, 3),
        ('Sacramento', 'California', 1.7, 5)]
stmt = "INSERT INTO test VALUES(?, ?, ?, ?)"
con.executemany(stmt, data)
con.commit()

你可能感兴趣的:(Python-数据分析)