Python的科学计算包- Pandas
Pandas
Pandas是Python Data Analysis Library或Pandas是基于NumPy的一种工具,该工具是为了解决数据分析任务而创建的。Pandas纳入了大量的库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。Pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是Python成为强大而高效的数据分析环境的重要因素之一。百度百科
本篇教程使用的所有资源文件下载地址:
- ex1.csv
- ex2.csv
- ex3.csv
- ex3.txt
- ex4.csv
- ex5.csv
- ex6.csv
- ex7.csv
- csv_mindex.csv
- frame_pickle
- out.csv
- test_file.csv
- tseries.csv
Pandas有两个主要的数据结构
- 1.Series
- 数组与标签
- 可以通过标签选取数据
- 定长的有序字典
- 2.Dataframe
- 表格型数据结构
- 行索引、列索引
Series的基本使用
1 | # coding: utf-8 |
DataFrame的基本使用
启蒙于R语言,它的同一列必须是同一种类型
可以面向”行”来操作,也可以面向”列”来操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196# coding: utf-8
import numpy as np
import pandas as pd
import sys
from pandas import Series, DataFrame
data = {"state": ["Ohio", "Utah", "California", "Nevada"],
"year": [2000, 2001, 2002, 2003],
"pop": [1.5, 1.7, 3.6, 2.4]}
# 由Pandas自动排序列的位置
frame = DataFrame(data)
print frame
'''
pop state year
0 1.5 Ohio 2000
1 1.7 Utah 2001
2 3.6 California 2002
3 2.4 Nevada 2003
'''
# 指定列的位置显示
frame = DataFrame(data, columns=["year", "state", "pop"])
print frame
'''
year state pop
0 2000 Ohio 1.5
1 2001 Utah 1.7
2 2002 California 3.6
3 2003 Nevada 2.4
'''
# 指定索引名称
frame2 = DataFrame(data, columns=["year", "state", "pop", "debt"], index=["one", "two", "three", "four"])
print frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Utah 1.7 NaN
three 2002 California 3.6 NaN
four 2003 Nevada 2.4 NaN
'''
print frame2.columns
'''
Index([u'year', u'state', u'pop', u'debt'], dtype='object')
'''
# 指定名称选取列的值
print frame2['state']
'''
one Ohio
two Utah
three California
four Nevada
Name: state, dtype: object
'''
# 也可以通过名称直接显示
print frame2.year
'''
one 2000
two 2001
three 2002
four 2003
Name: year, dtype: int64
'''
# 修改值
frame2["debt"] = 16.5
print frame2
'''
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Utah 1.7 16.5
three 2002 California 3.6 16.5
four 2003 Nevada 2.4 16.5
'''
# 赋值
frame2["debt"] = np.arange(4.)
print frame2
'''
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Utah 1.7 1.0
three 2002 California 3.6 2.0
four 2003 Nevada 2.4 3.0
'''
# 在数组里指定索引赋值
val = Series([-1.2, -1.5, -1.7], index=["two", "four", "five"])
frame2["debt"] = val
print frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Utah 1.7 -1.2
three 2002 California 3.6 NaN
four 2003 Nevada 2.4 -1.5
'''
# 添加一列并且等于Ohio的值,才是Bool类型
frame2["eastern"] = frame2.state == "Ohio"
print frame2
'''
year state pop debt eastern
one 2000 Ohio 1.5 NaN True
two 2001 Utah 1.7 -1.2 False
three 2002 California 3.6 NaN False
four 2003 Nevada 2.4 -1.5 False
'''
# 删除列
del frame2["eastern"]
print frame2
'''
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Utah 1.7 -1.2
three 2002 California 3.6 NaN
four 2003 Nevada 2.4 -1.5
'''
# 字典嵌套,自动排序
pop = {"Nevada": {2001: 2.4, 2002: 2.9},
"Ohio": {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = DataFrame(pop)
print frame3
'''
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
'''
# 指定索引的排序方式
pop2 = DataFrame(pop, index=[2000, 2001, 2002, 2003])
print pop2
'''
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN
'''
print frame3.values
'''
[[ nan 1.5]
[ 2.4 1.7]
[ 2.9 3.6]]
'''
frame3.index.name = 'year'
frame3.columns.name = 'state'
print frame3
'''
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
'''
# 索引对象
obj = Series(range(3), index=["a", "b", "c"])
print obj
'''
a 0
b 1
c 2
'''
index = obj.index
print index
'''
Index([u'a', u'b', u'c'], dtype='object')
'''
# 这是不允许的
# index[1] = 'd'
# Index是一个类,有很多方法
index = pd.Index(np.arange(3))
print index
'''
Int64Index([0, 1, 2], dtype='int64')
'''
obj2 = Series([1.5, -2.5, 0], index=index)
print obj2.index is index # 输出 True
读写文本格式数据
Pandas提供一些用于将表格型数据读取为DataFrame对象的函数
函数:
- read_csv 逗号为分隔符
- read_table 制表符为分割符,如:’\t’
- read_fwf 没有分隔符,定宽列
- read_clipboard 读取剪切板中的数据
函数选项:
- 索引
- 类型推断和数据转换
- 日期解析
- 迭代
- 不规整数据问题
1 | # coding: utf-8 |
逐行读取文本文件
比如文件内容很大,我们不可能一下子把所有的内容直接从文件都读取出来,为了速度,我们可以指定多少行、指定多大的方式来读取1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39# coding: utf-8
import pandas as pd
from pandas import Series, DataFrame
# 读取一个大文件
result = pd.read_csv('pandas_data_files/ex6.csv')
print result
'''
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
...... 这里有一万行略过
[10000 rows x 5 columns]
'''
# 对指定的文件只读取5行
result1 = pd.read_csv('pandas_data_files/ex6.csv', nrows=5)
print result1
'''
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
'''
# 读取1000个字节的数据到变量chunker里
chunker = pd.read_csv('pandas_data_files/ex6.csv', chunksize=1000)
print chunker
tot = Series([])
for piece in chunker:
tot = tot.add(piece['key'].value_counts(), fill_value=0)
tot = tot.order(ascending=False)
print tot[:10]
在这里我用的Pandas v0.22.0,这是最新的版本,但是遇到了错误:AttributeError: 'Series' object has no attribute 'order'
我不知道怎么解决,如果有小伙伴知道,请分享以下
1 | # coding: utf-8 |
手工处理分隔符的方式
1 | # coding: utf-8 |
Excel文件的读取
因为很多的数据都是从Excel过来的,但是这两个组件需要安装,使用PyCharm如何安装呢? 看这篇文章,因为安装的方式是一样的,只不过名称不同
- Excel基本库,
- 读取:xlrd
- 写入:xlwt
- 基本电子表格交互
- 生成工作簿
- 从工作簿中读取数据
- 使用OpenPyxl
- 使用pandas读写
Excel中的数据类型和Python的数据类型对比
类型 编号 Python类型
XL_CELL_EMPTY 0 空字符串
XL_CELL_TEXT 1 Unicode字符串
XL_CELL_NUMBER 2 Float
XL_CELL_DATA 3 Float
XL_CELL_BOOLEAN 4 Int( 1 = True, 0 = False)
XL_CELL_ERROR 5 Int表示Excel内部编码
XL_CELL_BLANK 6 空字符串,仅当formatting into = True
实例讲解,读取和写入excel1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138# coding: utf-8
import numpy as np
import pandas as pd
import xlrd, xlwt
path = 'pandas_data_files'
# 生成一个工作簿
wb = xlwt.Workbook()
print wb
'''
我们看到打印的内存地址是0x109a7cb90,也就是说一张空的工作簿在此内存中
<xlwt.Workbook.Workbook object at 0x109a7cb90>
'''
# 添加一张工作表
wb.add_sheet('first_sheet', cell_overwrite_ok=True)
wb.get_active_sheet()
# 获取第一个工作簿
ws_1 = wb.get_sheet(0)
print ws_1
'''
<xlwt.Worksheet.Worksheet object at 0x10095e8d0>
'''
# 添加第二张工作表
ws_2 = wb.add_sheet('second_sheet')
# 生成一个8x8的矩阵
data = np.arange(1, 65).reshape((8, 8))
print data
'''
[[ 1 2 3 4 5 6 7 8]
[ 9 10 11 12 13 14 15 16]
[17 18 19 20 21 22 23 24]
[25 26 27 28 29 30 31 32]
[33 34 35 36 37 38 39 40]
[41 42 43 44 45 46 47 48]
[49 50 51 52 53 54 55 56]
[57 58 59 60 61 62 63 64]]
'''
# 例如:写入工作表
# 参数1:写入的行索引号
# 参数2:写入的列索引号
# 参数3:写入的值
# ws_1.write(0, 0, 100)
# 通过两个循环,将行和列的每个值写入到工作表
for c in range(data.shape[0]):
for r in range(data.shape[1]):
ws_1.write(r, c, data[c, r])
ws_2.write(r, c, data[c, r])
# 保存到硬盘
wb.save(path + '/workbook.xls')
# 默认保存的是2003版的excel,如果是2007版的话,就是后缀名改下就行
# 现在可以去你的硬盘查看内容,两个工作表的内容都是一样的
# 接下来,从工作簿中读取
book = xlrd.open_workbook(path + '/workbook.xls')
print book
'''
现在已经读取到内存中了
<xlrd.book.Book object at 0x1107bae10>
'''
# 打印看有几个工作表
print book.sheet_names()
'''
[u'first_sheet', u'second_sheet']
'''
# 通过名字读取工作表
sheet_1 = book.sheet_by_name('first_sheet')
# 通过索引获取工作表
sheet_2 = book.sheet_by_index(1)
print sheet_2.name
'''
second_sheet
'''
# 有多少列,有多少行
print sheet_1.ncols, sheet_1.nrows
'''
8 8
'''
# 比如:我们查看第一行,第一列的值,和值类型
c1 = sheet_1.cell(0, 0)
print c1.value
print c1.ctype
'''
1.0
2
'''
# 2表示Float,对于Excel的数据类型和Python的数据类型的关系,详见上面那个表格
# 从第三列开始读,起始行3,结束行7
print sheet_1.col_values(3, start_rowx=3, end_rowx=7)
'''
[28.0, 29.0, 30.0, 31.0]
'''
# 我们用Python的循环完全展现工作表
for c in range(sheet_1.ncols):
for r in range(sheet_1.nrows):
print '%i' % sheet_1.cell(r, c).value,
print
'''
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
'''
# 但是,如果使用pandas,则是相当的简单
xls_file = pd.ExcelFile(path + '/workbook.xls')
table = xls_file.parse('first_sheet')
print table
'''
1 9 17 25 33 41 49 57
0 2 10 18 26 34 42 50 58
1 3 11 19 27 35 43 51 59
2 4 12 20 28 36 44 52 60
3 5 13 21 29 37 45 53 61
4 6 14 22 30 38 46 54 62
5 7 15 23 31 39 47 55 63
6 8 16 24 32 40 48 56 64
'''
# 我们看到读取出来的DataFrame类型的数据
JSON数据
JSON数据(JavaScript Object Notation)
数据类型:
- 对象
- 数组
- 字符串
- 数值
- 布尔值
- null
JSON库的loads方法,JSON这个工具是自带的。
1 | # coding: utf-8 |
二进制数据格式的读取和写入
pickle存储的数据格式是短期的存储,不能永远保存数据永远是正确的,所以仅仅是用于短期和临时的存储1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# coding: utf-8
import pandas as pd
# 读取文件
frame = pd.read_csv('pandas_data_files/ex1.csv')
print 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('pandas_data_files/ex1_pickle_binary_out.csv')
# 读取二进制文件
print pd.read_pickle('pandas_data_files/ex1_pickle_binary_out.csv')
'''
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
'''
HDF5格式
HDF5介绍 是一种数据格式,用于大量的数据进行科学计算,可移植性高,可扩展型高。
很大大型机构的数据存储格式都采用了HDF5,比如:NASA的地球观测系统,MATLAB等等。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48# coding: utf-8
import h5py
import numpy as np
# 数据
imgData = np.arange(24).reshape((2, 3, 4))
print imgData
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
# 写入硬盘
f = h5py.File('pandas_data_files/HDF5_file.h5', 'w')
f['data'] = imgData
f['labels'] = range(24)
f.close()
# 从硬盘读取
f = h5py.File('pandas_data_files/HDF5_file.h5', 'r')
# 查看所有的主键
print f.keys()
'''
[u'data', u'labels']
'''
# 查看主键为data的所有的值
a = f['data'][:]
print a
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
'''
f.close()
使用HTML和Web API
需要安装request工具1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43# coding: utf-8
import requests
import json
from pandas import DataFrame
# 从网址读取数据
url = 'https://api.github.com/repos/pydata/pandas/milestones/28/labels'
resp = requests.get(url)
print resp
'''
<Response [200]>
'''
# 读取到json对象
data = json.loads(resp.text)
print data
'''
[{u'url': u'https://api.github.com/repos/pandas-dev/pandas/labels/Bug', u'color': u'e10c02', u'default': False, u'id': 76811, ......}]
'''
# 将json对象转成DataFrame
issue_labels = DataFrame(data)
print issue_labels
'''
color default id name \
0 e10c02 False 76811 Bug
1 4E9A06 False 76812 Enhancement
2 FCE94F False 127681 Refactor
3 75507B False 129350 Build
4 3465A4 False 134699 Docs
5 AFEEEE False 211840 Timeseries
......
url
0 https://api.github.com/repos/pandas-dev/pandas...
1 https://api.github.com/repos/pandas-dev/pandas...
2 https://api.github.com/repos/pandas-dev/pandas...
3 https://api.github.com/repos/pandas-dev/pandas...
4 https://api.github.com/repos/pandas-dev/pandas...
5 https://api.github.com/repos/pandas-dev/pandas...
......
'''
使用数据库
自带sqlite31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63# coding: utf-8
import sqlite3
from pandas import DataFrame
# 创建一张表
query = """
CREATE TABLE test
(a VARCHAR(20), b VARCHAR(20), c REAL, d INTEGER);
"""
# 创建数据库
conn = sqlite3.connect('pandas_data_files/mydb.sqlite')
# 执行sql语句
conn.execute(query)
conn.commit()
# 插入数据
data = [('Atlanta', 'Georgia', 1.25, 6),
('Tallahassee', 'Florida', 2.7, 3),
('Sacramento', 'California', 1.9, 6)]
stmt = "insert into test values(?,?,?,?);"
# 执行插入命令
conn.executemany(stmt, data)
conn.commit()
# 查询数据
cursor = conn.execute("select * from test")
rows = cursor.fetchall()
print rows
'''
[(u'Atlanta', u'Georgia', 1.25, 6), (u'Tallahassee', u'Florida', 2.7, 3), (u'Sacramento', u'California', 1.9, 6)]
'''
# 查看数据表示几列
print cursor.description
'''
(('a', None, None, None, None, None, None), ('b', None, None, None, None, None, None), ('c', None, None, None, None, None, None), ('d', None, None, None, None, None, None))
'''
# 使用DataFrame读取数据
print DataFrame(rows, columns=zip(*cursor.description)[0])
'''
a b c d
0 Atlanta Georgia 1.25 6
1 Tallahassee Florida 2.70 3
2 Sacramento California 1.90 6
'''
# 或者pandas有对sql的接口读取
import pandas.io.sql as sql
print sql.read_sql("select * from test", conn)
'''
a b c d
0 Atlanta Georgia 1.25 6
1 Tallahassee Florida 2.70 3
2 Sacramento California 1.90 6
'''