pandas变形函数
长表变宽表
povit() 函数
pivot 英语释义 = 中心点,中心事物。
计算机理解: 把数据的聚集到一个中心点, 长 变 宽 就是其中的一种形式
功能: 长表变宽表的函数
代码实战:
import pandas as pd
df = pd.DataFrame({'Class':[1,1,2,2],
'Name':['San Zhang','San Zhang','Si Li','Si Li'],
'Subject':['Chinese','Math','Chinese','Math'],
'Grade':[80,75,90,85]})
print(df)
print("*"*66)
print(df.pivot(index='Name', columns='Subject', values='Grade'))
运行结果:
Class Name Subject Grade
0 1 San Zhang Chinese 80
1 1 San Zhang Math 75
2 2 Si Li Chinese 90
3 2 Si Li Math 85
******************************************************************
Subject Chinese Math
Name
San Zhang 80 75
Si Li 90 85
从上面的我们可以知道:povit() 的 三大参数。
df.povit(index = "", columns = "" , values = "")
index = "" --> 新的行索引index = 原来的列表头
columns = "" --> 新的列表头 = 原来列的分类值(且这个值是**唯一的分类值**,不然会发生歧义,因为有多个,多个对应了不同的值,不知道往哪个分类值中进行填充。)
values = "" --> 新的值 = 除去充当columns的原来的值
以上这三个参数同样支持多级索引;
代码如下:
import pandas as pd
df = pd.DataFrame({'Class':[1, 1, 2, 2, 1, 1, 2, 2],
'Name':['San Zhang', 'San Zhang', 'Si Li', 'Si Li',
'San Zhang', 'San Zhang', 'Si Li', 'Si Li'],
'Examination': ['Mid', 'Final', 'Mid', 'Final',
'Mid', 'Final', 'Mid', 'Final'],
'Subject':['Chinese', 'Chinese', 'Chinese', 'Chinese',
'Math', 'Math', 'Math', 'Math'],
'Grade':[80, 75, 85, 65, 90, 85, 92, 88],
'rank':[10, 15, 21, 15, 20, 7, 6, 2]})
pivot_multi = df.pivot(index = ['Class', 'Name'],
columns = ['Subject','Examination'],
values = ['Grade','rank'])
print(pivot_multi)
运行效果:
Grade rank
Subject Chinese Math Chinese Math
Examination Mid Final Mid Final Mid Final Mid Final
Class Name
1 San Zhang 80 75 90 85 10 15 20 7
2 Si Li 85 65 92 88 21 15 6 2
注意:
根据唯一性原则,新表的行索引等价于对 index 中的多列使用 drop_duplicates ,而列索引的长度为 values中的元素个数乘以 columns 的唯一组合数量(与 index 类似)。
如果不满足唯一性条件,那么必须通过聚合操作使得相同行列组合对应的多个值变为一个值。
代码实例:
import pandas as pd
df = pd.DataFrame({'Name':['San Zhang', 'San Zhang',
'San Zhang', 'San Zhang',
'Si Li', 'Si Li', 'Si Li', 'Si Li'],
'Subject':['Chinese', 'Chinese', 'Math', 'Math',
'Chinese', 'Chinese', 'Math', 'Math'],
'Grade':[80, 90, 100, 90, 70, 80, 85, 95]})
df.pivot(index="Name", columns="Subject", values="Grade")
运行结果(错误显示):
ValueError: Index contains duplicate entries, cannot reshape
这里的 Name 是多个分类值,pivot() 函数难以处理多分类值进行转换成宽表
povit_table() 函数
为了解决变形函数 pivot() 难以处理多分类值的这种现象,我们在这里引入:povit_table() 函数
import pandas as pd
df = pd.DataFrame({'Name':['San Zhang', 'San Zhang',
'San Zhang', 'San Zhang',
'Si Li', 'Si Li', 'Si Li', 'Si Li'],
'Subject':['Chinese', 'Chinese', 'Math', 'Math',
'Chinese', 'Chinese', 'Math', 'Math'],
'Grade':[80, 90, 100, 90, 70, 80, 85, 95]})
print(df.pivot_table(index="Name", columns="Subject", values="Grade"))
运行结果:
Subject Chinese Math
Name
San Zhang 85 95
Si Li 75 90
针对分类值进行函数操作的方法:
代码实战:
print(df.pivot_table(index="Name", columns="Subject", values="Grade", aggfunc="mean"))
运行结果:
Subject Chinese Math
Name
San Zhang 85 95
Si Li 75 90
虽然两处的运行结果一样,但是含义确不一样,
aggfunc = "聚合函数" = aggerate function
是针对多个类别使用去使用函数
再比如:
print(df.pivot_table(index="Name", columns="Subject", values="Grade", aggfunc="sum"))
运行结果:
Subject Chinese Math
Name
San Zhang 170 190
Si Li 150 180
此处的聚合函数方法具体可参照:
(聚合函数章节)
宽表变长表
melt() 函数
melt = 熔化,融化
计算机理解:融化了之后,就扩散了,因此变长了。
功能: 将宽表变成长表
代码实战:
df = pd.DataFrame({'Class':[1,2],
'Name':['San Zhang', 'Si Li'],
'Chinese':[80, 90],
'Math':[80, 75]})
df_melted = df.melt(id_vars = ['Class', 'Name'],
value_vars = ['Chinese', 'Math'],
var_name = 'Subject',
value_name = 'Grade')
print(df)
print("*"*66)
print(df_melted)
运行结果:
Class Name Chinese Math
0 1 San Zhang 80 80
1 2 Si Li 90 75
******************************************************************
Class Name Subject Grade
0 1 San Zhang Chinese 80
1 2 Si Li Chinese 90
2 1 San Zhang Math 80
3 2 Si Li Math 75
根据上述可知:
melted的四大参数:
id_vars = 列名
value_vars = 作为宽表的列类别
var_name = 作为长表的列名
value_name = 原列变量的值
注意:
上面的 povit() 和 melt() 函数参数的对比。
在列索引中被压缩的一组值对应的列元素只能代表同一层次的含义
wide_to_long()函数
为了解决上面的只能代表同一层含义,因此引入wide_to_long()的函数。
df = pd.DataFrame({'Class':[1,2],'Name':['San Zhang', 'Si Li'],
'Chinese_Mid':[80, 75], 'Math_Mid':[90, 85],
'Chinese_Final':[80, 75], 'Math_Final':[90, 85]})
pd.wide_to_long(df,
stubnames=['Chinese', 'Math'],
i = ['Class', 'Name'],
j='Examination',
sep='_',
suffix='.+')
运行结果:
Chinese Math
Class Name Examination
1 San Zhang Mid 80 90
Final 80 90
2 Si Li Mid 75 85
Final 75 85
从结果看,参数的含义是:
pd.wide_to_long(df, stubnames = ["待处理的分类类别1", "待处理的分类类别2", "", ……],
i = ["列表头元素1", "列表头元素2", "", ……],
j = "待处理类别的所属类别",
sep = "怎样把待处理类别分隔开来",
suffix= "正则后缀")
正则后缀:是行索引压缩到列名时,需要符合什么样的条件。