问题描述
我有以下DataFrame:
Police Product PV1 PV2 PV3 PM1 PM2 PM3
0 1 AA 10 8 14 150 145 140
1 2 AB 25 4 7 700 650 620
2 3 AA 13 22 5 120 80 60
3 4 AA 12 6 12 250 170 120
4 5 AB 10 13 5 500 430 350
5 6 BC 7 21 12 1200 1000 900
PV1是第1年的PV项目,第2年的PV2...。 我想将重塑和分组操作结合一些重命名,以获取下面的DF:
Product Item Year1 Year2 Year3
0 AA PV 35 36 31
1 AA PM 520 395 320
2 AB PV 35 17 12
3 AB PM 1200 1080 970
4 BC PV 7 21 12
5 BC PM 1200 1000 900
它通过对产品名称进行操作进行分组,并调整DF的形状以将该项目作为一列传递,并将每个列的总和放入新的列年中。
我尝试了一些测试,但没有成功。 如果您有任何想法,我将不胜感激。
感谢您的帮助
解决方法
第一个想法是通过DataFrame.set_index
将第一列转换为MultiIndex
,然后将数字和非数字值提取到MultiIndex
并进行赋值,最后通过DataFrame.stack
重新整形并通过DataFrame.add_prefix
:
df1 = df.set_index(['Police','Product'])
L = df1.columns.str.extract('(\D+)(\d+)').T.to_numpy().tolist()
df1.columns = pd.MultiIndex.from_arrays(L,names=['Item',None])
df1 = df1.stack(level=0).add_prefix('Year').reset_index()
print (df1)
Police Product Item Year1 Year2 Year3
0 1 AA PM 150 145 140
1 1 AA PV 10 8 14
2 2 AB PM 700 650 620
3 2 AB PV 25 4 7
4 3 AA PM 120 80 60
5 3 AA PV 13 22 5
6 4 AA PM 250 170 120
7 4 AA PV 12 6 12
8 5 AB PM 500 430 350
9 5 AB PV 10 13 5
10 6 BC PM 1200 1000 900
11 6 BC PV 7 21 12
或使用wide_to_long
:
df1 = (pd.wide_to_long(df,i=['Police','Product'],stubnames=['PM','PV'],j='tmp')
.rename_axis('Item',axis=1)
.stack()
.unstack(2)
.add_prefix('year')
.rename_axis(None,axis=1)
.reset_index())
print (df1)
Police Product Item year1 year2 year3
0 1 AA PM 150 145 140
1 1 AA PV 10 8 14
2 2 AB PM 700 650 620
3 2 AB PV 25 4 7
4 3 AA PM 120 80 60
5 3 AA PV 13 22 5
6 4 AA PM 250 170 120
7 4 AA PV 12 6 12
8 5 AB PM 500 430 350
9 5 AB PV 10 13 5
10 6 BC PM 1200 1000 900
11 6 BC PV 7 21 12