pandas.DataFrame中2列之间的分组功能?

时间:2014-03-03 05:07:33

标签: pandas grouping correlation

我的数据框有多个数值数据列和一个“组”列。我希望在每个组的两个列上获得各种函数的输出。

示例数据和功能:

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方式,如果有的话。

1 个答案:

答案 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。