如何删除Pandas DataFrame中每行嵌套列表的最后一个元素
问题根因
你的遍历代码报错的核心原因是df.iterrows()每次迭代返回的是**(行索引, 该行对应的Series对象)**的二元元组,你没有对元组做拆包,直接把整个元组作为行标签传给df.loc[],pandas无法把包含Series的元组识别为合法的行索引,因此抛出TypeError: unhashable type: 'Series'错误。你之前单行代码df.loc[0, 'Activities'].pop()能正常运行,正是因为传入了明确的合法行索引0,可以准确定位到目标单元格的列表对象。
实现方案
推荐方案:apply向量化处理(无显式遍历,效率最高)
不需要手写循环,直接对Activities列的每个列表做切片去掉最后一位即可,代码简洁且运行效率远高于显式遍历:
df["Activities"] = df["Activities"].apply(lambda lst: lst[:-1])
处理后得到的结果符合预期:
CaseID Activities 0 0 [10, 16, 577] 1 1 [355, 10, 16, 577] 2 2 [355, 578, 578, 16] 3 3 [355, 12, 546, 438] 4 4 [577, 180, 12, 79]
修正后的遍历写法
如果你一定要用循环+pop()原地修改的逻辑,只需要正确拆包iterrows()返回的元组,拿到每行的索引即可:
# 拆包为idx(行索引)和row(行数据)两个变量 for idx, row in df.iterrows(): df.loc[idx, "Activities"].pop()
注意:
pop()是列表的原地修改方法,执行后不需要重新赋值,会直接修改原DataFrame中存储的列表对象。但这种显式遍历的方式在数据量较大时运行速度会明显慢于apply方案,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者Andre Link
相关产品推荐
相关产品推荐

