我正在尝试使用.groupby
与pandas
dataframe
进行多次计算,并使用以下数据:
import numpy as np
import pandas as pd
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : np.random.randn(8),
'D' : np.random.randn(8)})
In [2]: df
Out[2]:
A B C D
0 foo one 0.469112 -0.861849
1 bar one -0.282863 -2.104569
2 foo two -1.509059 -0.494929
3 bar three -1.135632 1.071804
4 foo two 1.212112 0.721555
5 bar two -0.173215 -0.706771
6 foo one 0.119209 -1.039575
7 foo three -1.044236 0.271860
我想以更短更快的方式计算以下输出:
A B var1 var2 var3
bar one 0.000000 0.000000 0.000000
three 0.000000 0.000000 0.000000
two 0.000000 0.000000 0.000000
foo one 0.822999 19.705290 0.731207
three 0.000000 0.000000 0.000000
two 0.229541 5.509553 0.697971
目前我知道如何以单独的方式做到这一点:
# lambda functions to apply
diff = lambda x: max(x)-min(x)
per = lambda x: (max(x)-min(x))/max(x)
ratio1 = lambda x: (max(x)-min(x))/ len(x)
# grouping using col C
df.groupby(['A','B'])['C'].apply(diff) # var1
#Grouping using col D
df.groupby(['A','B'])['D'].apply(per) # var2
df.groupby(['A','B'])['D'].apply(ratio1) #var3
编辑: 我知道如何在数据帧中加入所有结果,但我想知道如何在一个中执行这3个操作。任何建议都被接受,即使不是因为性能低下也不能做到一切......
答案 0 :(得分:2)
您可以使用agg()
:
df.groupby(['A','B']).agg({'C': diff, 'D': [per, ratio1]})
要跳过重命名部分,您可以调用函数var1
,var2
和var3
并在groupby
中使用它。
var1 = lambda x: max(x)-min(x)
var2 = lambda x: (max(x)-min(x))/max(x)
var3 = lambda x: (max(x)-min(x))/ len(x)
df.groupby(['A','B']).agg({'C': var1, 'D': [var2, var3]})
df.columns = df.columns.droplevel()
修改强>
尝试:
def var1(x): return max(x)-min(x)
def var2(x): return (max(x)-min(x))/max(x)
def var3(x): return (max(x)-min(x))/ len(x)
编辑编辑
这适用于我pandas
版本0.19.2
:
import numpy as np
import pandas as pd
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three',
'two', 'two', 'one', 'three'],
'C' : np.random.randn(8),
'D' : np.random.randn(8)})
def var1(x): return max(x)-min(x)
def var2(x): return (max(x)-min(x))/max(x)
def var3(x): return (max(x)-min(x))/ len(x)
df = df.groupby(['A','B']).agg({'C': var1, 'D': [var2, var3]})
df.columns = df.columns.droplevel()