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)
您应该检查累积和是否等于最大累积和值,而不是检查累积和是否大于 1,这相当于获取[ @Onyambumask.sum()建议]。
df.loc[(mask.cumsum() == mask.sum()) & mask, 'c'] = 'x'
Run Code Online (Sandbox Code Playgroud)
对于用于标记满足条件的最后一个值的掩码,请使用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)