如何高效处理含重复索引的pd.Series:保留首尾True值
处理带重复索引的Series,保留每组第一个和最后一个True值
针对你描述的需求,这里提供两种解决方案,分别兼顾可读性和处理效率:
方法一:分组+自定义函数(直观易懂)
先构造你的示例数据:
import pandas as pd # 创建示例Series s = pd.Series( [False, False, False, True, True, True, True, True, False], index=["FA155"] * 9 )
然后定义一个处理单个分组的函数,找到组内所有True的位置,仅保留第一个和最后一个:
def keep_first_last_true(group): # 获取组内所有True的索引 true_indices = group[group].index # 如果True数量少于2,直接返回原组(保留现有True) if len(true_indices) < 2: return group # 创建全False的结果Series result = pd.Series(False, index=group.index) # 标记第一个和最后一个True的位置 result.loc[true_indices[0]] = True result.loc[true_indices[-1]] = True return result
最后按索引分组应用函数:
result = s.groupby(level=0).apply(keep_first_last_true)
输出结果:
FA155 False FA155 False FA155 False FA155 True FA155 False FA155 False FA155 False FA155 True FA155 False dtype: bool
方法二:矢量化transform(高效处理大数据)
如果你的数据集很大,apply的性能可能不够理想,推荐使用矢量化的transform方法,避免循环:
def first_last_true(group): # 标记第一个True:累计True数量为1且当前值为True first_true = (group.cumsum() == 1) & group # 标记最后一个True:倒序累计True数量为1且当前值为True last_true = (group.iloc[::-1].cumsum() == 1) & group # 合并两个标记 return first_true | last_true result = s.groupby(level=0).transform(first_last_true)
原理说明:
group.cumsum()会累计组内True的数量(True等价于1,False等价于0),第一个True的位置累计和恰好为1;group.iloc[::-1].cumsum()倒序累计True数量,最后一个True的位置倒序累计和为1;- 用
& group确保只有原本为True的位置才会被标记,避免把False位置误转为True; - 最后取两个标记的并集,就得到仅保留第一个和最后一个True的结果。
这种方法完全基于Pandas的矢量化操作,处理速度比apply快很多,适合大规模数据。
内容的提问来源于stack exchange,提问作者yatu
相关产品推荐
相关产品推荐

