计算Pandas DataFrame中每一行在给定列中同一组中有多少行具有较大的值

时间:2019-09-28 01:43:06

标签: python-3.x pandas pandas-groupby

我有一个熊猫数据框,其中包含一个分组字段和感兴趣的变量。对于数据帧中的每一行,我要计算同一组中有多少行具有所关注变量的较大值。

下面是我要实现的目标的一个示例:

import pandas as pd
df = pd.DataFrame(data = [['a',1],['a',2],['a',2],['a',3],['b',4],['b',2],['b',6]],
                  columns = ['groups','value'])
df
  groups value
0   a      1
1   a      2
2   a      2
3   a      3
4   b      4
5   b      2
6   b      6

这是我希望收到的输出:

  groups value what_i_want
0   a      1        3
1   a      2        1
2   a      2        1
3   a      3        0
4   b      4        1
5   b      2        2
6   b      6        0

我知道我可以通过遍历数据帧的每一行来得到这个答案,但是我也知道遍历数据帧的行是最后的选择,而我的完整数据集要大得多,这需要很长时间才能运行。我假设有一些使用groupby或apply进行此操作的方法,但我无法弄清楚。

谢谢!

2 个答案:

答案 0 :(得分:1)

为每个组使用Numpy广播:

def summarize(group):
    v = group['value'].values
    other = v[:, None]
    count = (other > v).sum(axis=0)

    return pd.DataFrame({'what_i_want': count})

df.groupby('groups').apply(summarize)

说明

让我们考虑组a。我们首先将values中的元素提取到一个名为v的numpy数组中:

v = [1, 2, 2, 3] # ndarray of shape (4,)

我们想将此数组与其自身进行正交比较,并计算有多少个元素大于当前元素。 [:, None]的语法是为了提高v的维度...

other = [[1], [2], [2], [3]] # ndarray of shape (4,1)

...使得other > v操作可广播,并且比较矩阵如下所示:

other > v
            v:  [ 1   2   2   3 ]
other:  [
         [1]      F   F   F   F
         [2]      T   F   F   F
         [2]      T   F   F   F
         [3]      T   T   T   F
        ]
----------------------------------
sum(axis=0)       3   1   1   0

答案 1 :(得分:1)

IIUC rank

(-df.value).groupby(df['groups']).rank(method='min')-1
Out[466]: 
0    3.0
1    1.0
2    1.0
3    0.0
4    1.0
5    2.0
6    0.0
Name: value, dtype: float64

#df['what i want']=(-df.value).groupby(df['groups']).rank(method='min')-1