Pandas处理列表值列:筛选特定序列记录报错解决
解决Pandas中列表类型列的筛选问题
嘿,这个问题我之前也碰到过!你报错的KeyError: -1根源在于没分清Pandas Series和普通Python列表的索引逻辑:直接对df.stage_seq用[-1]时,Pandas会把它当成要取整个Series的最后一行数据,而不是遍历每个列表元素取其最后一项,自然找不到-1这个行索引,就报错了。
下面给你两种靠谱的处理方法:
方法一:用apply+lambda快速筛选
这是最直接的方式,专门针对这种单条件的筛选需求:
# 保留不满足「最后阶段是E且倒数第二阶段是D」的记录 df = df[df['stage_seq'].apply(lambda x: not (x[-1][0] == 'E' and x[-2][0] == 'D'))]
简单解释下:
df['stage_seq'].apply(lambda x: ...)会逐个遍历stage_seq列里的每个列表元素x- 对每个列表
x,我们检查它最后一个元组的第一个值(x[-1][0])是不是'E',同时倒数第二个元组的第一个值(x[-2][0])是不是'D' - 用
not取反,就能把符合删除条件的行(也就是id=3的记录)排除掉
方法二:拆分列表后分组判断(适合复杂场景)
如果你后续还要对这些阶段数据做更多操作,比如统计每个id的阶段数量、提取特定位置的阶段,这种拆分后分组的方式会更灵活:
# 把每个列表拆成多行,保留原id的关联 exploded_df = df.explode('stage_seq', ignore_index=False) # 按id分组,取出每个id对应的倒数第二和最后一个阶段 last_two_stages = exploded_df.groupby('id')['stage_seq'].nth([-2, -1]).unstack() # 提取每个阶段的名称(元组的第一个值) last_two_stages = last_two_stages.applymap(lambda x: x[0]) # 筛选出不符合删除条件的id valid_ids = last_two_stages[(last_two_stages[0] != 'D') | (last_two_stages[1] != 'E')].index # 用合法id过滤原DataFrame df = df[df['id'].isin(valid_ids)]
额外提醒
如果你的数据里存在列表长度小于2的记录,直接用x[-2]会触发索引错误,建议先过滤掉这类无效数据:
# 先筛掉列表长度不足2的行 df = df[df['stage_seq'].apply(len) >= 2]
内容的提问来源于stack exchange,提问作者Edamame
相关产品推荐
相关产品推荐

