本文是DataWhale组队学习pandas变形部分的学习总结。
练习1:美国非法药物数据集
现有一份关于美国非法药物的数据集,其中SubstanceName, DrugReports分别指药物名称和报告数量:
df =pd.read_csv('../data/drugs.csv').sort_values(['State','COUNTY','SubstanceName'],ignore_index=True)
df
第一问 将数据转为如下的形式:
首先利用pivot将DataFrame转为行多级索引形式,列索引指定为年份,值为药物报告数量,若不存在则自动填充NaN
df_new = df.pivot(index=['State','COUNTY','SubstanceName'],columns='YYYY',values='DrugReports')
df_new
然后利用reset_index()函数(表示是否要把去掉的索引层丢弃),这里重置所有索引。
df_new.reset_index()
最后利用rename_axis()将列名YYYY改为空。
df_new = df_new.reset_index().rename_axis(columns={'YYYY':''})
df_new
第二问 将第一问中的结果恢复为原表。
首先利用melt函数将宽表转为长表。
df_melted = df_new.melt(id_vars = ['State','COUNTY','SubstanceName'],
value_vars = [2010,2011,2012,2013,2014,2015,2016,2017],
var_name = 'YYYY',
value_name = 'DrugReports')
df_melted
~是取反符号,就是将表中DrugReports这一列数值为NaN的记录给去掉。
df_resume = df_melted[~(df_melted.DrugReports).isin(['NaN'])]
df_resume
将State列和YYYY列顺序交换。
df_resume = df_resume[['YYYY','State','COUNTY','SubstanceName','DrugReports']]
df_resume
最终在按照’State’,‘COUNTY’,'SubstanceName’进行排序恢复成原表。
df_resume.sort_values(['State','COUNTY','SubstanceName'],ignore_index=True)
第三问 按State分别统计每年的报告数量总和,其中State, YYYY分别为列索引和行索引,要求分别使用pivot_table函数与groupby+unstack两种不同的策略实现,并体会它们之间的联系。
利用pivot_table函数进行处理。
df_one = df.pivot_table(index='YYYY',columns='State',values='DrugReports',aggfunc='sum')
利用groupby+unstack函数进行处理。
df_two = df.groupby(['YYYY','State'])['DrugReports'].sum()
df_two
df_two.unstack()
练习二 特殊的wide_to_long方法
从功能上看,melt方法应当属于wide_to_long的一种特殊情况,即stubnames只有一类。请使用wide_to_long生成melt一节中的df_melted。(提示:对列名增加适当的前缀)
df = pd.DataFrame({'Class':[1,2],
'Name':['San Zhang', 'Si Li'],
'Chinese':[80, 90],
'Math':[80, 75]})
df
df.columns
给列名前加上适当的前缀(即Grade)
df.rename(columns={'Chinese':'Grade_Chinese','Math':'Grade_Math'},inplace=True)
df.columns
查看修改完列名之后的DataFrame
df
利用wide_to_long函数进行处理。
pd.wide_to_long(df,
stubnames='Grade',
i=['Class','Name'],
j='Subject',
sep='_',
suffix='.+').reset_index()