
长宽表的变形

- pivot
pivot变形的过程
ch5_pivot.png
ch5_mulpivot.png
- pivot_table
pivot_table的变形依赖唯一性条件,当不能满足唯一性条件时,可以使用pivot_table,使用聚合操作使得相同行列组合对应的多个值变成一个值
df.pivot_table(index = 'Name',
columns = 'Subject',
values = 'Grade',
aggfunc='mean',
margins=True)
- melt
pivot的逆操作
ch5_melt.png
- wide_to_long
如果列中包含了交叉类别,比如期中期末的类别和语文数学的类别,那么想要把values_name对应的Grade扩充为两列分别对应语文分数和数学分数,只把期中期末的信息压缩,这种需求下就要使用wide_to_long函数来完成
ch5_wtl.png
索引的变形

- unstack
把行索引变为列索引,主要参数是移动的层号,默认是最内层,同时支持转化多个层
df.unstack()
df.unstack(2)
df.unstack([0,2])
其他函数变形

- crosstable
crosstab并不是一个值得推荐使用的函数,因为它能实现的所有功能pivot_table都能完成,并且速度更快。在默认状态下,crosstab可以统计元素组合出现的频数。
【练一练】
前面提到了crosstab
的性能劣于pivot_table
,请选用多个聚合方法进行验证。
%timeit -n 500 pd.crosstab(index = df.School, columns = df.Transfer, values = [0]*df.shape[0], aggfunc = 'count')
%timeit -n 500 df.pivot_table(index = 'School',columns = 'Transfer',values = 'Name',aggfunc = 'count')
%timeit -n 500 pd.crosstab(index = df.School, columns = df.Transfer, values = df.Height, aggfunc = 'sum')
%timeit -n 500 df.pivot_table(index = 'School',columns = 'Transfer',values = 'Name',aggfunc = 'sum')

- explode
explode
参数能够对某一列的元素进行纵向的展开,被展开的单元格必须存储list, tuple, Series, np.ndarray
中的一种类型。
df_ex = pd.DataFrame({'A': [[1, 2], 'my_str', {1, 2}, pd.Series([3, 4])],
'B': 1})
df_ex
df_ex.explode('A')


- get_dummies
特征构建的重要函数之一,用于把类别特征转为指示变量
pd.get_dummies(df.Grade).head()

练习
Ex1:美国非法药物数据集
现有一份关于美国非法药物的数据集,其中SubstanceName, DrugReports
分别指药物名称和报告数量:
-
将数据转为如下的形式:
Data
-
将第1问中的结果恢复为原表。
-
按
State
分别统计每年的报告数量总和,其中State, YYYY
分别为列索引和行索引,要求分别使用pivot_table
函数与groupby+unstack
两种不同的策略实现,并体会它们之间的联系
# 使用pivot
df_op = df.pivot(index=['State','COUNTY','SubstanceName'], columns='YYYY', values='DrugReports').reset_index().rename_axis(columns={'YYYY':''})
df_op.head()
# 使用melt恢复为原表
df_op_melted = df_op.melt(id_vars = ['State','COUNTY','SubstanceName'],
value_vars = df_op.columns[3:],
var_name = 'YYYY',
value_name = 'DrugReports').dropna(subset=['DrugReports'])
# 使用pivot按state统计每年的和
df_op_melted.pivot_table(index = ['State'],
columns = 'YYYY',
values = 'DrugReports',
aggfunc = 'sum').head()
# 使用groupby+unstack实现
df_op_melted.groupby(['State', 'YYYY'])['DrugReports'].agg(['sum']).unstack()
Ex2:特殊的wide_to_long方法
从功能上看,melt
方法应当属于wide_to_long
的一种特殊情况,即stubnames
只有一类。请使用wide_to_long
生成melt
一节中的df_melted
。(提示:对列名增加适当的前缀)
df = df.rename(columns={'Chinese':'Grade_Chinese', 'Math':'Grade_Math'})
pd.wide_to_long(df,stubnames=['Grade'],
i = ['Class', 'Name'],
j='Subject',
sep='_',
suffix='.+').reset_index()
网友评论