pandas思维导图扩充
练习
一、现有一份关于美国非法药物的数据集,其中 SubstanceName, DrugReports 分别指药物名称和报告数量:
- 将数据转为如下的形式:
import numpy as np
import pandas as pd
df = pd.read_csv('data/drugs.csv').sort_values(['State','COUNTY','SubstanceName'],ignore_index=True)
print(df.head(3))
dft = df.pivot(index=['State', 'COUNTY', 'SubstanceName'], columns='YYYY', values='DrugReports').reset_index().\
rename_axis(columns={'YYYY':''}) #变形后重设置索引并重命名原YYYY列
print(dft)
- 将第 1 问中的结果恢复为原表。
dft_melted = dft.melt(id_vars = ['State', 'COUNTY', 'SubstanceName'],value_vars = dft.columns[-8:],var_name = 'YYYY',
value_name = 'DrugReports').dropna(subset = ['DrugReports'])
print(dft_melted)
- 按 State 分别统计每年的报告数量总和,其中 State, YYYY 分别为列索引和行索引,要求分别使用
pivot_table 函数与 groupby+unstack 两种不同的策略实现,并体会它们之间的联系。
# 策略一:
df_sum = df.pivot_table(index = 'YYYY',columns = 'State', values = 'DrugReports', aggfunc = 'sum')
print(df_sum.head(3))
# 策略二:
res = df.groupby(['State', 'YYYY'])['DrugReports'].sum().unstack(0)
print(res)
二、特殊的 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.rename(columns = {'Chinese':'pre_Chinese', 'Math': 'pre_Math'})
dfwtl = pd.wide_to_long(df,stubnames=['pre'],i = ['Class', 'Name'],j='Subject',sep='_',suffix='.+').reset_index().rename(columns={'pre':'Grade'})
print(dfwtl)