如果初始groupby找不到满足掩码条件的第一行,如何更改groupby列?

问题描述 投票:0回答:1

这是我的数据框:

import pandas as pd
df = pd.DataFrame(
    {
        'main': ['x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'y', 'y', 'y', 'y', 'y', 'y', 'y'],
        'sub': ['c', 'c', 'c', 'd', 'd', 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', 'g'],
        'num_1': [10, 9, 80, 80, 99, 101, 110, 222, 90, 1, 7, 10, 2, 10, 95, 10],
        'num_2': [99, 99, 99, 102, 102, 209, 209, 209, 209, 100, 100, 100, 100, 90, 90, 90]
    }
)

这是我的预期输出。我想添加列

result
:

   main sub  num_1  num_2  result
0     x   c     10     99     101
1     x   c      9     99     101
2     x   c     80     99     101
3     x   d     80    102     110
4     x   d     99    102     110
5     x   e    101    209     222
6     x   e    110    209     222
7     x   e    222    209     222
8     x   e     90    209     222
9     y   f      1    100     NaN
10    y   f      7    100     NaN
11    y   f     10    100     NaN
12    y   f      2    100     NaN
13    y   g     10     90      95
14    y   g     95     90      95
15    y   g     10     90      95

面膜是:

mask = (df.num_1 > df.num_2)

过程是这样开始的:

a)

groupby
列是
sub

b) 找到满足每组掩码条件的第一行。

c)

num_1
的值放入
result

如果没有满足掩码条件的行,则将

groupby
列更改为
main
以查找
mask
的第一行。此阶段有条件:

使用

subs
作为
main
列时,不应考虑之前的
groupby

d
列中
sub
组的上述步骤示例:

a)

sub
groupby
列。

b)

d
组中没有行
df.num_1 > df.num_2

所以现在对于组

d
,它的
main
组被搜索。然而,
c
组也属于这个
main
组。由于它位于
d
组之前,因此
c
组不应计入此步骤。

在这张图片中,我展示了这些值的来源:

这是我的尝试。它部分解决了某些群体的问题,但不是全部:

def step_a(g):
    mask = (g.num_1 > g.num_2)

    g.loc[mask.cumsum().eq(1) & mask, 'result'] = g.num_1
    g['result'] = g.result.ffill().bfill()
    return g

a = df.groupby('sub').apply(step_a)
python pandas dataframe group-by
1个回答
0
投票

代码

定义自定义函数

def get_result(d):
    cond = d['num_1'].gt(d['num_2'])
    if cond.sum() > 0:
        return pd.Series(d['num_1'].where(cond).bfill().iloc[0], index=d.index)
    else:
        df1 = df[df['main'].eq(d['main'].iloc[0])]
        s1 = df1['num_2'].where(df1['sub'].eq(d['sub'].iloc[0])).ffill()
        target = df1['num_1'].where(df1['num_1'].gt(s1)).bfill().iloc[0]
        return pd.Series(target, index=d.index)

制作

result
专栏

df['result'] = df.groupby(
    ['main', 'sub'], group_keys=False, sort=False).apply(get_result)

df:

   main sub  num_1  num_2  result
0     x   c     10     99   101.0
1     x   c      9     99   101.0
2     x   c     80     99   101.0
3     x   d     80    102   110.0
4     x   d     99    102   110.0
5     x   e    101    209   222.0
6     x   e    110    209   222.0
7     x   e    222    209   222.0
8     x   e     90    209   222.0
9     y   f      1    100     NaN
10    y   f      7    100     NaN
11    y   f     10    100     NaN
12    y   f      2    100     NaN
13    y   g     10     90    95.0
14    y   g     95     90    95.0
15    y   g     10     90    95.0
© www.soinside.com 2019 - 2024. All rights reserved.