在处理大量数据的时候,使用一个人见人爱的pandas库作为工具实在令人快意,现在,我们就简单学习一下pandas的使用。
转载请注明出处
先说一个坑:不知道为什么,点击charmpy自动运行ipynb文件的时候,matplotlib.pyplot无法加载,而在charmpy的终端里输入ipython notebook来启动却没有这个问题,这真是让人困惑,如果哪位大神了解原因,请不吝赐教。(当然,这并不是什么大问题)
开始说正事:
官方文档是我们最好的朋友,强烈建议不要看我的博客,直接对照官方文档学习。。。
明确两个概念:
1、Series
就是带索引的表格了
可以初始化一个Series
import pandas as pd
import numpy as np
s = pd.Series([1,2,3,4],index=[4,3,2,1])
print(s)
output:
4 1
3 2
2 3
1 4
dtype: int64
第一列就是数据的index,第二列是数据本身,我很无耻的把1,2,3,4的index设置成了4,3,2,1
你可以对这个Series进行加减乘除,这实际上就是为每个数据进行该运算
也可以对数据进行移动
print(s * 3)
print(s.shift(2)) #数据整体向下移动两格
4 3
3 6
2 9
1 12
dtype: int64
4 NaN
3 NaN
2 1.0
1 2.0
dtype: float64
如果被运算项也是一个Series,那么就会对两个Series的对应项进行相应计算:
b = pd.Series([6,5,7,8],index=[3,4,2,1])
print(a + b)
output:
1 12
2 10
3 8
4 6
dtype: int64
这里,a和b的对应项相加了,这里所谓的对应项就是index对应的项,这一点可以从我调换了5,6数据的位置看出来。
Series具有很大的宽容度, 具体来说,就是它允许index有重复,也允许两个数据相加的时候没有对应的index,这个时候相加项为NaN,我们可以从下面代码中体会这一点
s = pd.Series([1,2,3,4,5],index=[4,3,2,2,np.nan])
b = pd.Series([6,5,7,8,9],index=[3,4,2,1,np.nan])
print(a + s)
output:
1.0 NaN #b中没有index为1的,所以结果为NaN
2.0 10.0 #s中有两个index为2,所以分别和b中的2相加,这里是3+7
2.0 11.0 #s中有两个index为2,所以分别和b中的2相加,这里是4+7
3.0 8.0
4.0 6.0
NaN 14.0 #意外的收获!NaN也可以作为一个Index,但是不建议这样做
dtype: float64
这就是Series的基本结构了,Series也是一个类,当我们阅读代码或使用的时候,可以慢慢的体会它的方法调用。
2、DataFrame
DataFrame是pandas另一个重要的数据结构,如果说Series是一维数据,那么DataFrame就是二维的,我们先看一个简单的使用:
dates = pd.date_range('20150201', periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
print(df)
output:
A B C D
2015-02-01 -1.441677 0.312957 0.240162 -0.342640
2015-02-02 -0.071026 0.245586 -0.523156 -0.525295
2015-02-03 1.211075 0.428251 1.285046 -0.347892
2015-02-04 0.996403 -0.865883 -0.522793 -0.660043
2015-02-05 -1.161475 0.759567 1.746924 -0.112592
2015-02-06 0.462525 -0.066692 -1.712363 0.024872
这里,我们可以看到一个行和列都被标注的表格,这里,我们可以以多种方式检索这部分数据,如按行、按列、按index等
如下:
print(df[0:1]) #按行检索,这里必须写成区间的形式
print(' ')
print(df['A']) #按列检索,和字典的方法很像
print(df.loc[pd.Timestamp('20150202'),'A':'B']) #按index,这里index必须是实际的数据结构,而且调用loc方法
#loc方法有个小坑,那就是,使用loc输出的区间包括结束区间点,但是使用iloc的时候,不包括,和数组一样
print(df.iloc[0:2,0:2])
#按行检索
A B d D
2015-02-01 0.246012 -0.472071 -1.590799 -1.161207
#按列检索
2015-02-01 0.246012
2015-02-02 -0.727845
2015-02-03 0.799771
2015-02-04 -1.402293
2015-02-05 0.792754
2015-02-06 -0.553409
Freq: D, Name: A, dtype: float64
#按index检索
A 1.103339
B -0.371686
Name: 2015-02-02 00:00:00, dtype: float64
DataFrame中的数据结构可以很丰富,如下
df2 = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20130102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })
print(df2)
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
注意到,输入为非数组的,自动用输入值补全了。
可以使用at和iat对值进行设置:
df.at[dates[0],'A'] = 0
df.iat[1,1] = 0
print(df.iloc[0:2,0:2])
df2.at[1:3,'G'] = ['sig','sig2','sig3']
print(df2)#可以建立一个新行,或列,没有定义的位置将会用NaN补全
#注意,数据的位置必须明确,如以上新定义的G行只有三个数据,那对应的行编码一共也只有三个
output:
A B
2015-02-01 0.000000 1.314317
2015-02-02 1.103339 0.000000
A B C D E F G
0 1.0 2013-01-02 1.0 3 test foo NaN
1 1.0 2013-01-02 1.0 3 train foo sig
2 1.0 2013-01-02 1.0 3 test foo sig2
3 1.0 2013-01-02 1.0 3 train foo sig3
你还可以使用过滤的方法来查找数据:
print(df2[df2['E'].isin(['test'])])
print(df2[df2['d']>2])
output:
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
2 1.0 2013-01-02 1.0 3 test foo
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
DataFrame的一些计算:
DataFrame可以求均值、四则运算
print(df.mean()) #求均值
s = pd.Series([2,3,4,5,6,7],index=dates).shift(-2)
print(df.sub(2)) #全局求减法
print(df.sub(s,axis='index')) #每一列减去s中对应行的值
output:
A 0.244411
B 0.230149
C 0.615706
D 0.380204
dtype: float64
A B C D
2015-02-01 0.000000 0.400157 0.978738 2.240893
2015-02-02 1.867558 0.000000 0.950088 -0.151357
2015-02-03 -0.103219 0.410599 0.144044 1.454274
2015-02-04 0.761038 0.121675 0.443863 0.333674
2015-02-05 1.494079 -0.205158 0.313068 -0.854096
2015-02-06 -2.552990 0.653619 0.864436 -0.742165
A B C D
2015-02-01 -2.000000 -1.599843 -1.021262 0.240893
2015-02-02 -0.132442 -2.000000 -1.049912 -2.151357
2015-02-03 -2.103219 -1.589401 -1.855956 -0.545726
2015-02-04 -1.238962 -1.878325 -1.556137 -1.666326
2015-02-05 -0.505921 -2.205158 -1.686932 -2.854096
2015-02-06 -4.552990 -1.346381 -1.135564 -2.742165
A B C D
2015-02-01 -4.000000 -3.599843 -3.021262 -1.759107
2015-02-02 -3.132442 -5.000000 -4.049912 -5.151357
2015-02-03 -6.103219 -5.589401 -5.855956 -4.545726
2015-02-04 -6.238962 -6.878325 -6.556137 -6.666326
2015-02-05 NaN NaN NaN NaN
2015-02-06 NaN NaN NaN NaN
到这里为止,pandas最简单的一些应用就已经介绍完了,之后会补充一些更高阶的用法,敬请期待,代码见github