这是我的数据框:
import pandas as pd
df = pd.DataFrame(
{
'a': ['x', 'x', 'x', 'x', 'x', 'y', 'y', 'y', 'y', 'y', 'y', 'y'],
'b': [1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2],
'c': [9, 8, 11, 13, 14, 3, 104, 106, 11, 100, 70, 7]
}
)
预期输出:创建列
out
:
a b c out
0 x 1 9 NaN
1 x 1 8 NaN
2 x 1 11 NaN
3 x 2 13 found
4 x 2 14 NaN
5 y 1 3 NaN
6 y 1 104 found
7 y 1 106 NaN
8 y 2 11 NaN
9 y 2 100 NaN
10 y 2 70 NaN
11 y 2 7 NaN
面膜是:
mask = (df.c > 10)
流程:按列分组
a
:
a) 对于每个组,找到满足
mask
条件的第一行。
b) 对于组
x
,此条件仅适用于b == 2
。这就是选择第 3
行的原因。
这是我的尝试。已经很接近了,但感觉好像不是这样:
def func(g):
mask = (g.c > 10)
g.loc[mask.cumsum().eq(1) & mask, 'out'] = 'found'
return g
df = df.groupby('a').apply(func)
一个选项:
idx = mask.groupby(df['a']).idxmax()
df.loc[idx[mask.loc[idx].values], 'out'] = 'found'
另一个:
df.loc[mask & mask.groupby(df['a'])
.transform(lambda m: (~m).shift(fill_value=True)
.cummin()),
'out'] = 'found'
输出:
a b c out
0 x 1 9 NaN
1 x 1 8 NaN
2 x 1 11 found
3 x 2 13 NaN
4 x 2 14 NaN
5 y 1 3 NaN
6 y 1 104 found
7 y 1 106 NaN
8 y 2 11 NaN
9 y 2 100 NaN
10 y 2 70 NaN
11 y 2 7 NaN