【问题标题】:Propagating down the result of groupby aggregations向下传播 groupby 聚合的结果
【发布时间】:2014-04-10 00:12:24
【问题描述】:

假设我有以下 DataFrame

                       X         Y
A    B      C                    
bar  one    P   0.630667  1.457555
     three  Q   1.163132 -0.944378
            T   0.423349  0.432508
flux six    P  -1.055297 -0.419939
     three  T   2.064113  0.465885
foo  five   Q   0.271349  0.472808
            S  -0.985560 -0.301500
            P  -0.482336 -0.089823
            R   0.745047 -0.713639

我需要在B 的每个值中确定X 具有最高值的级别C 的值,并将其传播回每一行。

结果应该是:

                       X         Y  W
A    B      C                    
bar  one    P   0.630667  1.457555  P
     three  Q   1.163132 -0.944378  Q
            T   0.423349  0.432508  Q
flux six    P  -1.055297 -0.419939  P
     three  T   2.064113  0.465885  T
foo  five   Q   0.271349  0.472808  R
            S  -0.985560 -0.301500  R
            P  -0.482336 -0.089823  R
            R   0.745047 -0.713639  R

我该怎么做?

到目前为止,我有以下几点:

df.groupby(level=['A', 'B']).agg(lambda x: x.max())

但我不知道如何将结果“传播”到原始行。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    如果我理解你,你可以将transform(这是“向下传播”部分,虽然我一直认为它是向上传播)与idxmax结合起来:

    >>> df["W"] = df.groupby(level=["A", "B"])["X"].transform(lambda x: x.idxmax()[2])
    >>> df
                         X         Y  W
    A    B     C                       
    bar  one   P  0.630667  1.457555  P
         three Q  1.163132 -0.944378  Q
               T  0.423349  0.432508  Q
    flux six   P -1.055297 -0.419939  P
         three T  2.064113  0.465885  T
    foo  five  Q  0.271349  0.472808  R
               S -0.985560 -0.301500  R
               P -0.482336 -0.089823  R
               R  0.745047 -0.713639  R
    
    [9 rows x 3 columns]
    

    【讨论】:

    • 谢谢。我对适用于我在聚合中使用的 any lambda/函数的解决方案特别感兴趣(抱歉,最大 lambda 只是为了举例)。这适用于任何 lambda 吗?
    • 谢谢。它确实奏效了。我不敢相信它就像使用 transform 而不是 lambda 一样简单!
    【解决方案2】:

    想要一个不使用transform 的吗?

    In [101]:
    
    df2=pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(np.argmax).apply(lambda x: x[-1]))
    #or pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(lambda x: x.idxmax()[-1]))
    df['W']=df2.loc[df.index.droplevel(2)].values
    In [102]:
    
    print df
                         X         Y  W
    A    B     C                       
    bar  one   P  0.630667  1.457555  P
         three Q  1.163132 -0.944378  Q
               T  0.423349  0.432508  Q
    flux six   P -1.055297 -0.419939  P
         three T  2.064113  0.465885  T
    foo  five  P -0.482336 -0.089823  Q
               Q  0.271349  0.472808  Q
               R -0.745047 -0.713639  Q
               S -0.985560 -0.301500  Q
    
    [9 rows x 3 columns]
    

    这部分很容易得到, 在[115]中:

    print pd.DataFrame(df.groupby(level=['A', 'B'])['X'].agg(lambda x: x.idxmax()[-1]))
                X
    A    B       
    bar  one    P
         three  Q
    flux six    P
         three  T
    foo  five   Q
    
    [5 rows x 1 columns]
    

    但将其分配回'W' 并不那么严格

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-05
      • 2018-10-17
      • 1970-01-01
      • 2016-02-09
      • 2019-05-03
      • 2019-06-03
      • 2018-06-18
      • 2010-11-20
      相关资源
      最近更新 更多