testdf = pd.DataFrame({'mth':[1,1,1,1,1,1,1,1],'dy':[1,1,1,1,1,1,1,1],'id':[1,2,5,6,7,8,9,10], 'frame':['Fo','Fm','Fp','Fmp','Fp','Fmp','Fp','Fmp'],'param':['p1','p1','p1','p1','p2','p2','p3','p3'], 'avg':[0.1,0.25,0.1,0.25,0.08,0.26,0.05,0.25]}).set_index(['mth','dy'])
testdf2 = pd.DataFrame({'mth':[1,1,1,1,1,1,1,1],'dy':[2,2,2,2,2,2,2,2], 'id':[1,2,5,6,7,8,9,10], 'frame':['Fo','Fm','Fp','Fmp','Fp','Fmp','Fp','Fmp'], 'param':['p1','p1','p1','p1','p2','p2','p3','p3'],'avg':[0.1,0.25,0.1,0.25,0.08,0.26,0.05,0.25]}).set_index(['mth','dy'])
mydf = pd.concat([testdf,testdf2])
我有一些长格式的数据,需要基于param
对来为每个frame
计算新值。在下面的apply(print)语句中,您可以看到框架和参数之间的关系。不幸的是,对于我的第一个param
,我已经复制了数据-也许最简单的方法是删除与ID 5和6相对应的行。
mydf.groupby(['mth','dy','param']).apply(print)
id frame param avg
mth dy
1 1 1 Fo p1 0.10
1 2 Fm p1 0.25
1 5 Fp p1 0.10
1 6 Fmp p1 0.25
id frame param avg
mth dy
1 1 7 Fp p2 0.08
1 8 Fmp p2 0.26
id frame param avg
mth dy
1 1 9 Fp p3 0.05
1 10 Fmp p3 0.25
我考虑过的一种方法
mydf = mydf.query('(param!="p1") | (param=="p1" & (frame=="Fo" | frame=="Fm"))')
mydf.groupby(['mth','dy','param']).apply(lambda x: x.iloc[1].avg - x.iloc[0].avg)
但是,如果您的数据出现故障,您将得到错误的答案。我想使用pivot
或相关函数,以便可以使用Fm-Fo或Fmp-Fp的效果并按名称访问值。
但是,我似乎找不到找到将新列param_val
附加到每个param_val
都重复frame
的现有数据框中的解决方案。
至少,我认为我需要按p1
而不是p1
进行排序,例如。 mydf.query('param=="p1"')
和mydf.query('param!="p1"')
在进行透视之前,但应该有一个简洁的纵栏操作让我难以理解。
我确实看过Pivot duplicates rows into new columns Pandas,但还没绕过它。与R相比,在大熊猫中旋转非常复杂! 感谢您的帮助。谢谢!