1. 安装Pandas
windos下cmd:pip install pandas
导入pandas包:import pandas as pd
2. Series对象
带索引的一维数组
创建:
s = pd.Series([12,-4,7,9])
print (s)
0 12
1 -4
2 7
3 9
dtype: int64
s = pd.Series([12,-4,7,9], index = ['a', 'b', 'c', 'd'])
print (s)
a 12
b -4
c 7
d 9
dtype: int64
查看元素
print(s.values)
[12 -4 7 9]
查看索引标签
print(s.index)
Index(['a', 'b', 'c', 'd'], dtype='object')
使用NumPy数组定义Series对象
>>> arr = np.array([1,2,3,4])
>>> s3 = pd.Series(arr)
>>> s3
0 1
1 2
2 3
3 4
dtype: int32
使用Series对象也可以定义NumPy数组
>>> arr = np.array(s)
>>> arr
array([12, -4, 7, 9], dtype=int64)
Series对象当做字典
>>> dict = {'red':200, 'blue':20, 'orange':10}
>>> s = pd.Series(dict)
>>> s
blue 20
orange 10
red 200
dtype: int64
>>> dict
{'red': 200, 'orange': 10, 'blue': 20}
在上例的基础上
>>> dict = {'red':100, 'blue':30, 'black':50}
>>> ss = pd.Series(dict)
>>> ss + s
black NaN
blue 50.0
orange NaN
red 300.0
dtype: float64
>>> ss - s
black NaN
blue 10.0
orange NaN
red -100.0
dtype: float64
说明Series对象相运算都是取索引的标签的交集进行运算,没有交集的值为NaN
2. DataFrame对象
类似于Excel表。设计初衷是将Series由一维拓展到多维。
2.1. 定义
>>> data = {'color' : ['blue','green','yellow','red','white'],
... 'object' : ['ball','pen','pencil','paper','mug'],
... 'price' : [1.2,1.0,0.6,0.9,1.7]}
>>> frame = pd.DataFrame(data)
>>> frame
color object price
0 blue ball 1.2
1 green pen 1.0
2 yellow pencil 0.6
3 red paper 0.9
4 white mug 1.7
可以只创建部分的列
>>> frame2 = pd.DataFrame(data, columns=['object','price'])
>>> frame2
object price
0 ball 1.2
1 pen 1.0
2 pencil 0.6
3 paper 0.9
4 mug 1.7
和Series一样可以指明索引的标签
>>> frame3 = pd.DataFrame(data, index = ['a', 'b', 'c', 'd', 'e'])
>>> frame3
color object price
a blue ball 1.2
b green pen 1.0
c yellow pencil 0.6
d red paper 0.9
e white mug 1.7
使用np.array快速创建
>>> frame4 = pd.DataFrame(np.arange(16).reshape((4,4)), index = ['red', 'blue', 'yellow', 'white'], columns = ['ball', 'pen', 'pencil', 'paper'])
>>> frame4
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
使用嵌套字典创建(可以看出列是一级字典的键值,索引标签是二级字典的键值)
>>> dict = {'red' : {1000: 1, 2000: 2}, 'blue' : {3000: 3, 4000: 4}, 'orange' : {1000: 10, 3000: 30}}
>>> frame = pd.DataFrame(dict)
>>> frame
blue orange red
1000 NaN 10.0 1.0
2000 NaN NaN 2.0
3000 3.0 30.0 NaN
4000 4.0 NaN NaN
2.2. 选取元素
和Series类似,多了一个查看列名
>>> frame4.columns
Index(['ball', 'pen', 'pencil', 'paper'], dtype='object')
>>> frame4.index
Index(['red', 'blue', 'yellow', 'white'], dtype='object')
>>> frame4.values
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
查看列信息
>>> frame4['pencil']
red 2
blue 6
yellow 10
white 14
Name: pencil, dtype: int32
查看行信息
>>> frame4.ix[2]
ball 8
pen 9
pencil 10
paper 11
Name: yellow, dtype: int32
同时可以使用切片来查询行信息
>>> frame4[1:3]
ball pen pencil paper
blue 4 5 6 7
yellow 8 9 10 11
查找具体的元素,用索引和用索引的标签都是一样的(这里应该先用列再用行..本来都是习惯先行再列的)
>>> frame4['pencil'][1]
6
>>> frame4['pencil']['blue']
6
2.3. 赋值和删除
给index和columns设置标签
>>> frame4.index.name = '茵蒂克丝'(我只是个魔禁粉)
>>> frame4.columns.name = '考拉能丝'(为了协调)
>>> frame4
考拉能丝 ball pen pencil paper
茵蒂克丝
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
添加新的列
>>> frame4['new'] = [101, 102, 103, 104]
>>> frame4
考拉能丝 ball pen pencil paper new
茵蒂克丝
red 0 1 2 3 101
blue 4 5 6 7 102
yellow 8 9 10 11 103
white 12 13 14 15 104
>>> frame4['newnew'] = 1000
>>> frame4
考拉能丝 ball pen pencil paper new newnew
茵蒂克丝
red 0 1 2 3 101 1000
blue 4 5 6 7 102 1000
yellow 8 9 10 11 103 1000
white 12 13 14 15 104 1000
删除一列
>>> del frame4['new']
>>> frame4
考拉能丝 ball pen pencil paper newnew
茵蒂克丝
red 0 1 2 3 1000
blue 4 5 6 7 1000
yellow 8 9 10 11 1000
white 12 13 14 15 1000
2.4. 转置
很强大,把列变成行,行变成列
>>> frame4.T
茵蒂克丝 red blue yellow white
考拉能丝
ball 0 4 8 12
pen 1 5 9 13
pencil 2 6 10 14
paper 3 7 11 15
newnew 1000 1000 1000 1000
3. Index对象
3.1. Index的tips
索引是可以重复的
>>> s = pd.Series(range(6), index = ['white', 'blue', 'white', 'green', 'green', 'orange'])
>>> s
white 0
blue 1
white 2
green 3
green 4
orange 5
dtype: int32
一个标签对应多个元素,会得到一个Series对象。(DataFrame同理)
>>> s['green']
green 3
green 4
dtype: int32
3.2. Index的一些方法
返回索引值最大和最小的元素
>>> s.idxmax()
'orange'
>>> s.idxmin()
'white'
判断数据结构中是否存在重复的索引项
>>> s.index.is_unique
False
3.3. 更换索引
虽然数据结构一旦声明,Index对象不能改变,但是可以通过reindex方法改变索引标签。
>>> s = pd.Series([2,5,7,4], index = ['a', 'b', 'c', 'd'])
>>> s
a 2
b 5
c 7
d 4
dtype: int64
>>> s.reindex(['b', 'a', 'd', 'e'])
b 5.0
a 2.0
d 4.0
e NaN
dtype: float64
这个例子可以看出,可以更换索引标签的顺序,新的标签会赋值为NaN。
自动完成索引
>>> s = pd.Series([1,5,6,3], index = [0,3,5,6])
>>> s
0 1
3 5
5 6
6 3
dtype: int64
>>> s.reindex(range(7), method = 'ffill')
0 1
1 1
2 1
3 5
4 5
5 6
6 3
dtype: int64
>>> s.reindex(range(7), method = 'bfill')
0 1
1 5
2 5
3 5
4 6
5 6
6 3
dtype: int64
range(7)代表索引的值为0~6,method代表填充的方式.
'ffill'是新插入的索引,其元素为索引编号比它小的那一项的元素,例如索引1就使用索引0的元素,索引2使用索引1的元素。
'bfill'是新插入的索引,其元素为索引编号比它大的那一项的元素。
3.4. 删除
使用drop()方法删除。
>>> s
0 1
3 5
5 6
6 3
dtype: int64
>>> s.drop(3)
0 1
5 6
6 3
dtype: int64
>>> s.drop([0,6])
3 5
5 6
dtype: int64
删除DataFrame中的元素,需要指定元素两个轴的轴标签。
>>> frame = pd.DataFrame(np.arange(16).reshape(4, 4), index = ['red', 'blue', 'yellow', 'white'], columns = ['ball', 'pen', 'pencil', 'paper'])
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
删除行只需要指明行的标签
>>> frame.drop(['blue', 'white'])
ball pen pencil paper
red 0 1 2 3
yellow 8 9 10 11
删除列还要指明从哪个轴删除元素。
>>> frame.drop(['pen', 'pencil'], axis = 1)
ball paper
red 0 3
blue 4 7
yellow 8 11
white 12 15
4. DataFrame和Series之间的运算
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
>>> s = pd.Series(np.arange(4), ['ball', 'pen', 'pencil', 'paper'])
按照frame的列名生成Series
>>> s
ball 0
pen 1
pencil 2
paper 3
dtype: int32
>>> frame - s
ball pen pencil paper
red 0 0 0 0
blue 4 4 4 4
yellow 8 8 8 8
white 12 12 12 12
一一对应相减
调整一些s中'paper'和'pencil'的位置
>>> s = pd.Series(np.arange(4), ['ball', 'pen', 'paper', 'pencil'])
>>> frame - s
ball paper pen pencil
red 0 1 0 -1
blue 4 5 4 3
yellow 8 9 8 7
white 12 13 12 11
发现还是可以一一对应
新增一列'mug'
>>> s['mug'] = 10
>>> s
ball 0
pen 1
paper 2
pencil 3
mug 10
dtype: int64
>>> frame - s
ball mug paper pen pencil
red 0 NaN 1 0 -1
blue 4 NaN 5 4 3
yellow 8 NaN 9 8 7
white 12 NaN 13 12 11
发现会增加一列'mug‘但是元素值为NaN
5. 函数运用和映射
5.1. 按行或者列执行操作的函数
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
返回标量的apply()函数
>>> f = lambda x : x.max() - x.min()
用apply()函数在DataFrame对象上调用函数
默认是对列使用
>>> frame.apply(f)
ball 12
pen 12
pencil 12
paper 12
dtype: int64
对行使用需要将axis选项设置为1
>>> frame.apply(f, axis = 1)
red 3
blue 3
yellow 3
white 3
dtype: int64
返回Series对象的apply()函数
>>> def f(x):
... return pd.Series([x.min(), x.max()], index = ['min', 'max']) (index对应了DataFrame的index)
...
>>> frame.apply(f)
ball pen pencil paper
min 0 1 2 3
max 12 13 14 15
>>> frame.apply(f, axis = 1)
min max
red 0 3
blue 4 7
yellow 8 11
white 12 15
我的理解:这里其实就是对每一列都跑一次f函数,对每一列都返回一个函数的值,如果指明axis = 1,就是对每一行都跑一次f函数,对每一行返回一个函数值。
5.2. 统计函数
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
>>> frame.sum()
ball 24
pen 28
pencil 32
paper 36
dtype: int64
>>> frame.mean()
ball 6.0
pen 7.0
pencil 8.0
paper 9.0
dtype: float64
>>> frame.describe()
ball pen pencil paper
count 4.000000 4.000000 4.000000 4.000000 (返回不为NaN的元素个数)
mean 6.000000 7.000000 8.000000 9.000000 (返回平均值)
std 5.163978 5.163978 5.163978 5.163978 (返回标准差)
min 0.000000 1.000000 2.000000 3.000000
25% 3.000000 4.000000 5.000000 6.000000
50% 6.000000 7.000000 8.000000 9.000000
75% 9.000000 10.000000 11.000000 12.000000
max 12.000000 13.000000 14.000000 15.000000 (剩下的都能看懂)
6. 排序函数
6.1. 对Series排序
>>> s = pd.Series([5,0,3,8,4], index = ['red', 'blue', 'yellow', 'white', 'green'])
>>> s
red 5
blue 0
yellow 3
white 8
green 4
dtype: int64
按照索引名的字典序排序
>>> s.sort_index()
blue 0
green 4
red 5
white 8
yellow 3
dtype: int64
>>> s.sort_index(ascending=False) (降序)
yellow 3
white 8
red 5
green 4
blue 0
dtype: int64
按照值进行排序
>>> s.sort_values()
blue 0
yellow 3
green 4
red 5
white 8
dtype: int64
>>> s.sort_values(ascending=False)
white 8
red 5
green 4
yellow 3
blue 0
dtype: int64
书上写的是s.order(),但是自己实现起来出现错误,上网找了是sort_values()方法。
排位次操作(按照元素的值排位)
>>> s.rank()
red 4.0
blue 1.0
yellow 2.0
white 5.0
green 3.0
dtype: float64
>>> s.rank(ascending=False)
red 2.0
blue 5.0
yellow 4.0
white 1.0
green 3.0
dtype: float64
6.2. 对DataFrame排序
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
按照索引和列名排序
>>> frame.sort_index()
ball pen pencil paper
blue 4 5 6 7
red 0 1 2 3
white 12 13 14 15
yellow 8 9 10 11
>>> frame.sort_index(axis=1)
ball paper pen pencil
red 0 3 1 2
blue 4 7 5 6
yellow 8 11 9 10
white 12 15 13 14
注意这里都是对索引标签和对列名进行排序的,而不是按元素大小
按照值排序
按照列进行排序
>>> frame.sort_values(by='pen')
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
按照行进行排序
>>> frame.sort_values(by='blue', axis = 1)
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
这里书上应该是版本过旧,写的是sort_index()而不是sort_values()
7. 相关性和协方差
概念
相关性(correlation)
指两个变量之间的关系(或依赖关系)。
线性相关是指两个变量之间的直接关系。
相关性可以在-1(完全负相关)和+1(完美正相关)之间,0表示无线性关系。
协方差(covariance)
从直观上来看,协方差表示的是两个变量总体误差的期望。
如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值时另外一个也大于自身的期望值,那么两个变量之间的协方差就是正值;如果两个变量的变化趋势相反,即其中一个变量大于自身的期望值时另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。
二者关系
[r_{ξ,η} = frac{Cov(ξ,η)}{sqrt{Dξ}sqrt{Dη}}
]
其中r为相关性,Cov为协方差。
知乎上的解释
>>> frame
ball pen pencil paper
red 0 1 2 3
blue 4 5 6 7
yellow 8 9 10 11
white 12 13 14 15
用cov()和corr()计算协方差和相关系数
这个是书上写的,并不是很懂意义
>>> frame.corr()
ball pen pencil paper
ball 1.0 1.0 1.0 1.0
pen 1.0 1.0 1.0 1.0
pencil 1.0 1.0 1.0 1.0
paper 1.0 1.0 1.0 1.0
>>> frame.cov()
ball pen pencil paper
ball 26.666667 26.666667 26.666667 26.666667
pen 26.666667 26.666667 26.666667 26.666667
pencil 26.666667 26.666667 26.666667 26.666667
paper 26.666667 26.666667 26.666667 26.666667
计算某列和某列的相关系数和协方差:
>>> frame.ball.corr(frame.pen)
1.0
>>> frame.pen.cov(frame.ball)
26.666666666666664
用corrwith()计算DataFrame的列(axis=0,默认)或行(axis=1)跟另外一个Series或DataFrame之间的相关系数
>>> frame.corrwith(frame.pen)
ball 1.0
pen 1.0
pencil 1.0
paper 1.0
dtype: float64
>>> frame.corrwith(frame.ix[0], axis = 1)
red 1.0
blue 1.0
yellow 1.0
white 1.0
dtype: float64
8. NaN数据
8.1. 为元素赋值NaN
使用np.NaN
>>> s = pd.Series([0,1,2,np.NaN,9], index = ['red', 'blue', 'yellow', 'white', 'green'])
>>> s
red 0.0
blue 1.0
yellow 2.0
white NaN
green 9.0
dtype: float64
>>> s['white']
nan
8.2. 过滤NaN
删除Series中的NaN
使用dropna()函数或者使用notnull()筛选
>>> s.dropna()
red 0.0
blue 1.0
yellow 2.0
green 9.0
dtype: float64
>>> s[s.notnull()]
red 0.0
blue 1.0
yellow 2.0
green 9.0
dtype: float64
删除DataFrame中的NaN
>>> frame = pd.DataFrame([[6, np.NaN, 6], [np.NaN, np.NaN, np.NaN], [2, np.NaN, 5]], index = ['blue', 'green', 'red'], columns = ['ball', 'mug', 'pen'])
>>> frame
ball mug pen
blue 6.0 NaN 6.0
green NaN NaN NaN
red 2.0 NaN 5.0
使用dropna()只要行或列有一个NaN,该行或列就会被删除
>>> frame.dropna()
Empty DataFrame
Columns: [ball, mug, pen]
Index: []
可以发现因为每一行都有NaN,因此把每一行都删除了
用how指定值为'all',告知dropna()函数只删除所有元素均为NaN的行货列
>>> frame.dropna(how='all')
ball mug pen
blue 6.0 NaN 6.0
red 2.0 NaN 5.0
>>> frame.dropna(how='all', axis = 1)
ball pen
blue 6.0 6.0
green NaN NaN
red 2.0 5.0
8.3. 为NaN元素填充其他值
>>> frame
ball mug pen
blue 6.0 NaN 6.0
green NaN NaN NaN
red 2.0 NaN 5.0
对所有NaN都填充0
>>> frame.fillna(0)
ball mug pen
blue 6.0 0.0 6.0
green 0.0 0.0 0.0
red 2.0 0.0 5.0
指定列填充元素
>>> frame.fillna({'ball':1, 'mug':10, 'pen':0})
ball mug pen
blue 6.0 10.0 6.0
green 1.0 10.0 0.0
red 2.0 10.0 5.0
貌似无法指定行填充元素,如果有错请务必告诉我
>>> frame.fillna({'blue':1, 'green':100, 'red':0}, axis = 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:PythonPython3libsite-packagespandascoreframe.py", line 2754, in fillna
downcast=downcast, **kwargs)
File "E:PythonPython3libsite-packagespandascoregeneric.py", line 3639, in fillna
raise NotImplementedError('Currently only can fill '
NotImplementedError: Currently only can fill with dict/Series column by column
>>> frame.fillna({'blue':1, 'green':100, 'red':0})
ball mug pen
blue 6.0 NaN 6.0
green NaN NaN NaN
red 2.0 NaN 5.0
9. 等级索引和分级
多级索引
>>> s = pd.Series(np.random.rand(8), index = [['white', 'white', 'white', 'blue', 'blue', 'red', 'blue', 'red'], ['up', 'down', 'right', 'up', 'down', 'up', 'left', 'left']])
>>> s
white up 0.683135
down 0.206419
right 0.616636
blue up 0.010939
down 0.419153
red up 0.632491
blue left 0.060663
red left 0.713318
dtype: float64
>>> s.index
MultiIndex(levels=[['blue', 'red', 'white'], ['down', 'left', 'right', 'up']],
labels=[[2, 2, 2, 0, 0, 1, 0, 1], [3, 0, 2, 3, 0, 3, 1, 1]])
指明第一列索引
>>> s['blue']
up 0.010939
down 0.419153
left 0.060663
dtype: float64
指明第二列索引要类似切片用[:,第二列名],直接用[第二列名]会报错
>>> s[:,'up']
white 0.683135
blue 0.010939
red 0.632491
dtype: float64
>>> s['white','up']
0.68313456001550599
使用unstack()将使用等级索引的Series对象转换为一个DataFrame对象,把第二列索引转换为相应的列
>>> s.unstack()
down left right up
blue 0.419153 0.060663 NaN 0.010939
red NaN 0.713318 NaN 0.632491
white 0.206419 NaN 0.616636 0.683135
逆操作,使用stack()将DataFrame对象转换为Series对象,列名为第二列索引
>>> frame
ball mug pen
blue 6.0 NaN 6.0
green NaN NaN NaN
red 2.0 NaN 5.0
>>> frame.stack()
blue ball 6.0
pen 6.0
red ball 2.0
pen 5.0
dtype: float64
对DataFrame,为行和列都定义等级索引。
>>> frame1 = pd.DataFrame(np.random.rand(16).reshape(4, 4), index = [['white', 'white', 'red', 'red'], ['up', 'down', 'up', 'down']], columns = [['pen', 'pen', 'paper', 'paper'], [1, 2, 1, 2]])
>>> frame1
pen paper
1 2 1 2
white up 0.461711 0.907535 0.720078 0.706302
down 0.105371 0.673227 0.118255 0.401674
red up 0.339669 0.307175 0.831875 0.699694
down 0.946733 0.014064 0.716693 0.243006
9.1. 重新调整顺序和为层级排序
>>> frame1.columns.names = ['objects', 'id']
>>> frame1.index.names = ['colors', 'status']
>>> frame1
objects pen paper
id 1 2 1 2
colors status
white up 0.461711 0.907535 0.720078 0.706302
down 0.105371 0.673227 0.118255 0.401674
red up 0.339669 0.307175 0.831875 0.699694
down 0.946733 0.014064 0.716693 0.243006
交换层级
>>> frame1.swaplevel('colors', 'status')
objects pen paper
id 1 2 1 2
status colors
up white 0.461711 0.907535 0.720078 0.706302
down white 0.105371 0.673227 0.118255 0.401674
up red 0.339669 0.307175 0.831875 0.699694
down red 0.946733 0.014064 0.716693 0.243006
对某个层级的数据排序
书上用sortlevel()方法,应该还是旧版本原因
文档用的是sort_index()方法
>>> frame1.sort_index(level = 'colors')
objects pen paper
id 1 2 1 2
colors status
red down 0.946733 0.014064 0.716693 0.243006
up 0.339669 0.307175 0.831875 0.699694
white down 0.105371 0.673227 0.118255 0.401674
up 0.461711 0.907535 0.720078 0.706302
>>> frame1.sort_index(level = 'objects', axis = 1)
objects paper pen
id 1 2 1 2
colors status
white up 0.720078 0.706302 0.461711 0.907535
down 0.118255 0.401674 0.105371 0.673227
red up 0.831875 0.699694 0.339669 0.307175
down 0
9.2. 按层级统计数据
对指定的层级进行统计
>>> frame1.sum(level='status')
objects pen paper
id 1 2 1 2
status
down 1.052105 0.687291 0.834948 0.644681
up 0.801380 1.214710 1.551954 1.405997
>>> frame1.sum(level='id', axis=1)
id 1 2
colors status
white up 1.181789 1.613837
down 0.223626 1.074902
red up 1.171545 1.006870
down 1.663426 0.257070