- 10. Pandas的数据规整
- 10.1 层次化索引
- 10.2 数据连接
- 10.2.1 pd.merge
- 10.2.2 pd.concat
- 10.3 重塑
- 10.3.1 stack
- 10.3.2 unstack
- 10.4 轴向旋转
Pandas是一个强大的分析结构化数据的工具集,基于NumPy构建,提供了 高级数据结构和 数据操作工具,它是使Python成为强大而高效的数据分析环境的重要因素之一
(1) 一个强大的分析和操作大型结构化数据集所需的工具集
(2) 基础是NumPy,提供了高性能矩阵的运算
(3) 提供了大量能够快速便捷地处理数据的函数和方法
(4)应用于数据挖掘,数据分析
(5)提供数据清洗功能 10. Pandas的数据规整 10.1 层次化索引
Pandas的层次化索引简述,包括层级索引简介、内外层选取、交换等
#层次化索引
import numpy as np
import pandas as pd
data = pd.Series(np.random.randn(9),
index=[['a','a','a','b','b','c','c','d','d'],
[1,2,3,3,1,2,2,2,3]])
#内外层选取
data['b':'c']
data.loc[['b','d']]
data.loc[:,2]
frame = pd.Dataframe({'a':range(7),'b':range(7,0,-1),
'c':['one','one','one','two','two','two','two'],
'd':[0,1,2,0,1,2,3]})
#结果为:
# a b c d
#0 0 7 one 0
#1 1 6 one 1
#2 2 5 one 2
#3 3 4 two 0
#4 4 3 two 1
#5 5 2 two 2
#6 6 1 two 3
frame
#指定列转换为层次化索引
frame2 = frame.set_index(['c','d'])
#结果为:
# a b
#c d
#one 0 0 7
# 1 1 6
# 2 2 5
#two 0 3 4
# 1 4 3
# 2 5 2
# 3 6 1
frame2
#指定列转换为层次化索引,不删除指定列
#结果为:
# a b c d
#c d
#one 0 0 7 one 0
# 1 1 6 one 1
# 2 2 5 one 2
#two 0 3 4 two 0
# 1 4 3 two 1
# 2 5 2 two 2
# 3 6 1 two 3
frame.set_index(['c','d'],drop=False)
#消除层级索引
#结果为:
# c d a b
#0 one 0 0 7
#1 one 1 1 6
#2 one 2 2 5
#3 two 0 3 4
#4 two 1 4 3
#5 two 2 5 2
#6 two 3 6 1
frame2.reset_index()
10.2 数据连接
10.2.1 pd.merge
pd.merge(left,right,how=‘inner’,on=None,left_on=None,right_on=None):根据单个或多个键将不同Dataframe的行连接起来,类似数据库的连接操作。
- left:合并时左边的Dataframe
- right:合并时右边的Dataframe
- how:合并的方式默认’inner’,‘outer’,‘left’,‘right’
- on:需要合并的列名,必须两边都有的列名,并以left和right中的列名的交集作为连接键
- left_on:left Dataframe中用作连接键的列
- right_on:right Dataframe中用作连接键的列
#数据连接
left = pd.Dataframe({'key':['K0','K1','K2','K3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3']})
right = pd.Dataframe({'key':['K0','K1','K2','K3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3']})
#结果为:
# key A B
#0 K0 A0 B0
#1 K1 A1 B1
#2 K2 A2 B2
#3 K3 A3 B3
left
#结果为:
# key C D
#0 K0 C0 D0
#1 K1 C1 D1
#2 K2 C2 D2
#3 K3 C3 D3
right
#根据单个或多个键将不同的Dataframe的行连接起来,类似数据库的连接操作
#结果为:
# key A B C D
#0 K0 A0 B0 C0 D0
#1 K1 A1 B1 C1 D1
#2 K2 A2 B2 C2 D2
#3 K3 A3 B3 C3 D3
pd.merge(left,right)
#指定连接键(列)
pd.merge(left,right,on='key')
#处理重复列名
df_obj1 = pd.Dataframe({'key':['b','b','a','c','a','a','b'],
'data':np.random.randint(0,10,7)})
df_obj2 = pd.Dataframe({'key':['a','b','d'],
'data':np.random.randint(0,10,3)})
#添加后缀
#结果为:
# key data_left data_right
#0 b 9 1
#1 b 7 1
#2 b 3 1
#3 a 7 7
#4 a 8 7
#5 a 8 7
print(pd.merge(df_obj1,df_obj2,on='key',suffixes=('_left','_right')))
#按索引连接
#left_index=True或right_index=True
df_obj1 = pd.Dataframe({'key':['b','b','a','c','a','a','b'],
'data1':np.random.randint(0,10,7)})
df_obj2 = pd.Dataframe({'data2':np.random.randint(0,10,3)},index=['a','b','d'])
#left表根据key连接,right表根据索引连接
#结果为:
# key data1 data2
#0 b 7 0
#1 b 2 0
#6 b 8 0
#2 a 2 3
#4 a 8 3
#5 a 4 3
print(pd.merge(df_obj1,df_obj2,left_on='key',right_index=True))
#数据合并 join
left2 = pd.Dataframe([[1.,2.],[3.,4.],[5.,6.]],index = ['a','c','e'],columns=['语文','数学'])
right2 = pd.Dataframe([[7.,8.],[9.,10.],[11.,12.],[13.,14.]],index=['b','c','d','e'],columns=['英语','综合'])
#使用join进行索引连接,要求没有重叠的列名
#效果与pd.merge(left2,right2,how='outer',left_index=True,right_index=True)一致
left2.join(right2,how='outer')
10.2.2 pd.concat
沿着轴方向将多个对象合并到一起
- np.concat
#np.concat arr1 = np.random.randint(0,10,(3,4)) arr2 = np.random.randint(0,10,(3,4)) #结果为:(行合并) #[[8 8 4 0] # [7 0 1 2] # [3 0 9 3] # [6 4 2 7] # [3 3 9 0] # [3 5 3 9]] print(np.concatenate([arr1,arr2])) #结果为:(列合并) #[[8 8 4 0 6 4 2 7] # [7 0 1 2 3 3 9 0] # [3 0 9 3 3 5 3 9]] print(np.concatenate([arr1,arr2],axis=1))
- pd.concat
(1)注意指定轴方向,默认axis=0
(2)join指定合并方式,默认为outer
(3) Series合并时查看行索引有无重复
#pd.concat
#df1:
# one two
#a 0 1
#b 2 3
#c 4 5
df1 = pd.Dataframe(np.arange(6).reshape(3,2),index=list('abc'),columns=['one','two'])
#df2:
# one two
#a 0 1
#c 2 3
df2 = pd.Dataframe(np.arange(4).reshape(2,2),index=list('ac'),columns=['one','two'])
#默认外连接 axis=0 (常用)
#结果为:
# one two
#a 0 1
#b 2 3
#c 4 5
#a 0 1
#c 2 3
pd.concat([df1,df2])
#结果为:
# one two one two
#a 0 1 0.0 1.0
#b 2 3 NaN NaN
#c 4 5 2.0 3.0
pd.concat([df1,df2],axis=1)
10.3 重塑
10.3.1 stack
(1) 将列索引旋转为行索引,完成层级索引
(2)Dataframe -> Series
###重塑层次化索引
data = pd.Dataframe(np.arange(6).reshape((2,3)),
index = pd.Index(['老王','小刘'],name='姓名'),
columns = pd.Index(['语文','数学','英语'],name='科目'))
#科目 语文 数学 英语
#姓名
#老王 0 1 2
#小刘 3 4 5
data
#stack将列索引旋转为行索引,完成层级索引
r = data.stack()
#结果为:
#姓名 科目
#老王 语文 0
# 数学 1
# 英语 2
#小刘 语文 3
# 数学 4
# 英语 5
print(r)
#结果为:
print(type(r))
10.3.2 unstack
(1)将层级索引展开
(2)Series -> Dataframe
(3)默认操作内层索引(即level=-1),可通过设置level指定操作索引的级别
#将层级索引展开
#结果为:
#科目 语文 数学 英语
#姓名
#老王 0 1 2
#小刘 3 4 5
r.unstack()
#可简写为r.unstack('姓名')
#结果为:
#姓名 老王 小刘
#科目
#语文 0 3
#数学 1 4
#英语 2 5
r.unstack(level = '姓名')
a1 = pd.Series(np.arange(4),index=list('abcd'))
a2 = pd.Series([4,5,6],index=list('cde'))
#结果为:
#data1 a 0
# b 1
# c 2
# d 3
#data2 c 4
# d 5
# e 6
s1 = pd.concat([a1,a2],keys=['data1','data2'])
#结果为:pandas.core.series.Series
type(s1)
#结果为:
# a b c d e
#data1 0.0 1.0 2.0 3.0 NaN
#data2 NaN NaN 4.0 5.0 6.0
s1.unstack()
#stack()默认过滤缺失数据(例如NaN值),可通过设置dropna=False不过滤缺失值
#结果为:
#data1 a 0.0
# b 1.0
# c 2.0
# d 3.0
# e NaN
#data2 a NaN
# b NaN
# c 4.0
# d 5.0
# e 6.0
s1.unstack().stack()
10.4 轴向旋转
#轴向旋转
df3 = pd.Dataframe({'date':['2018-11-22','2018-11-22','2018-11-23','2018-11-23','2018-11-24'],
'class':['a','b','b','c','c'],
'values':[5,3,2,6,1]},columns=['date','class','values'])
# date class values
#0 2018-11-22 a 5
#1 2018-11-22 b 3
#2 2018-11-23 b 2
#3 2018-11-23 c 6
#4 2018-11-24 c 1
df3
#结果为:
#class a b c
# date
# 2018-11-22 5.0 3.0 NaN
# 2018-11-23 NaN 2.0 6.0
# 2018-11-24 NaN NaN 1.0
df3.pivot('date','class','values')
#结果为:
# values
#class a b c
# date
# 2018-11-22 5.0 3.0 NaN
# 2018-11-23 NaN 2.0 6.0
# 2018-11-24 NaN NaN 1.0
df3.set_index(['date','class']).unstack('class')



