这是我的数据框:
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
列。
d
b)组中没有行df.num_1 > df.num_2
所以现在对于 group d
,它的main
组被搜索。然而组c
也在这个main
组中。由于它位于 group 之前d
,因此 groupc
不应计入此步骤。
在这张图片中,我展示了这些值的来源:
这就是我的尝试。它部分解决了某些群体的问题,但不是全部:
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)
代码
定义自定义函数
制作
result
专栏df:
IIUC,您可以使用numpy广播为每个“main”形成一个掩码,并使用它来查找第一个 num1>num2,同时仅考虑下一组:
请注意,您可以轻松调整掩码以执行其他逻辑(在接下来的 n 组中搜索、排除除前一组之外的所有先前组等)。
输出:
中间掩码
m
,这里是第二个例子: