我的数据框有多个数值数据列和一个“组”列。我希望在每个组的两个列上获得各种函数的输出。
示例数据和功能:
df = pandas.DataFrame({"Dummy":[1,2]*6, "X":[1,3,7]*4,
"Y":[2,3,4]*4, "group":["A","B"]*6})
def RMSE(X):
return(np.sqrt(np.sum((X.iloc[:,0] - X.iloc[:,1])**2)))
我想做点什么
group_correlations = df[["X", "Y"]].groupby('group').apply(RMSE)
但是,如果我这样做,“组”列不在数据框中。如果我反过来这样做,就像这样:
group_correlations = df.groupby('group')[["X", "Y"]].apply(RMSE)
然后列选择不起作用:
df.groupby('group')[['X', 'Y']].head(1)
Dummy X Y group
group
A 0 1 1 2 A
B 1 2 3 3 B
仍然包含虚拟列,因此该函数将根据错误的数据计算RMSE。
有什么办法可以做我想做的事吗?我知道我可以对不同的组进行for循环,并手动选择列,但我更喜欢用pandas方式,如果有的话。
答案 0 :(得分:1)
这看起来像一个错误(或者没有实现抓取groupby中的多个列?),解决方法是直接传入groupby列:
In [11]: df[['X', 'Y']].groupby(df['group']).apply(RMSE)
Out[11]:
group
A 4.472136
B 4.472136
dtype: float64
要看到它是一样的:
In [12]: df.groupby('group')[['X', 'Y']].apply(RMSE) # wrong
Out[12]:
group
A 8.944272
B 7.348469
dtype: float64
In [13]: df.iloc[:, 1:].groupby('group')[['X', 'Y']].apply(RMSE) # correct: ignore dummy col
Out[13]:
group
A 4.472136
B 4.472136
dtype: float64
要完全避免这种情况,您可以更改RMSE以按名称选择列:
In [21]: def RMSE2(X, left_col, right_col):
return(np.sqrt(np.sum((X[left_col] - X[right_col])**2)))
In [22]: df.groupby('group').apply(RMSE2, 'X', 'Y') # equivalent to passing lambda x: RMSE2(x, 'X', 'Y'))
Out[22]:
group
A 4.472136
B 4.472136
dtype: float64
感谢@ naught101指出了甜蜜的apply语法以避免lambda。