查找满足掩码条件的最后一行

Ami*_*mir 6 python indexing duplicates pandas

这是我的数据框:

df = pd.DataFrame({'a': [20, 21, 333, 444], 'b': [20, 20, 20, 20]})
Run Code Online (Sandbox Code Playgroud)

c我想使用这个掩码创建列:

mask = (df.a >= df.b)
Run Code Online (Sandbox Code Playgroud)

我想获取满足此条件的最后一行并创建列c。我想要的输出如下所示:

     a   b    c
0   20  20  NaN
1   21  20  NaN
2  333  20  NaN
3  444  20  x
Run Code Online (Sandbox Code Playgroud)

我尝试了下面的代码,但它不起作用:

df.loc[mask.cumsum().gt(1) & mask, 'c'] = 'x'
Run Code Online (Sandbox Code Playgroud)

man*_*055 5

您应该检查累积和是否等于最大累积和值,而不是检查累积和是否大于 1,这相当于获取[ @Onyambumask.sum()建议]

df.loc[(mask.cumsum() == mask.sum()) & mask, 'c'] = 'x'
Run Code Online (Sandbox Code Playgroud)

代码演示

  • 请注意,这是一个相当简单的修复:`df.loc[(mask.cumsum() == mask.sum()) & mask, 'c'] = 'x'` (2认同)

cot*_*ail 4

对于用于标记满足条件的最后一个值的掩码,请使用duplicated()保留最后一个。我们知道mask最多包含 2 个值(True/False)。如果我们可以创建另一个掩码,将最后一次出现的这些值标记为 True,那么我们可以将其与mask自身链接起来以获得所需的掩码。这是通过以下~mask.duplicated(keep='last')方式实现的mask.duplicated(keep='last'):除了最后一次出现之外,flags 重复为 True,因此它的否定给出了我们想要的结果。

df = pd.DataFrame({'a': [20, 21, 333, 444], 'b': [20, 20, 20, 20]})
mask = (df.a >= df.b)

df['c'] = pd.Series('x', df.index).where(mask & ~mask.duplicated(keep='last'))
Run Code Online (Sandbox Code Playgroud)

如果你想切片/分配,那么你也可以使用这个链式掩码。

df.loc[mask & ~mask.duplicated(keep='last'), 'c'] = 'x'
Run Code Online (Sandbox Code Playgroud)

@mandy8055 的答案的较短版本是调用idxmax()以获取最高总和的索引(尽管这在 pandas 2.1.0 上显示 FutureWarning)。正如 @mozway 所指出的,只要 中至少有一个 True 值,这种方法就有效mask

df.loc[mask.cumsum().idxmax(), 'c'] = 'x'
Run Code Online (Sandbox Code Playgroud)

结果