如何基于zone列条件删除DataFrame中value列的连续重复行
看起来你是想针对每个zone,只保留value发生变化的行——也就是同一个zone下,如果后续行的value和该zone上一次出现的value相同,就删掉这行。你的初始思路方向有点偏,而且代码里还有几个小问题,我来帮你搞定这个需求。
先说说你原来代码的问题
- 你在循环里试图给列表
data_category_range用字典键赋值,这肯定会报错,列表只能用索引访问,应该用字典来存储每个zone的子DataFrame。 - 你最后用的去重逻辑是对整个DataFrame的连续行做比较,而不是按zone分组后比较,这根本不符合你的需求。
最优解决方案(高效简洁)
完全不需要动态生成变量,用pandas的分组和移位操作就能轻松搞定,特别适合你10000行的大型数据集:
首先,先构造你的示例数据(方便演示):
import pandas as pd data = { 'zone': [0,1,2,3,0,1,2,3], 'value': [12,12,99,12,12,12,12,99] } df_a = pd.DataFrame(data)
然后,用groupby按zone分组,对value列做移位操作,得到每个zone上一次出现的value:
# 为每个zone生成上一行的value(第一行没有上一行,会显示NaN) df_a['prev_value'] = df_a.groupby('zone')['value'].shift()
最后,筛选出「是该zone的第一行(prev_value为空)」或者「当前value和上一次的value不同」的行,再删掉辅助列:
# 保留符合条件的行 result = df_a[df_a['value'] != df_a['prev_value']].drop('prev_value', axis=1)
运行后得到的result就是你想要的结果:
zone value 0 0 12 1 1 12 2 2 99 3 3 12 6 2 12 7 3 99
这个方法的优势:
- 完全避免了动态变量的麻烦,嵌套循环里也能轻松使用,不用操心变量命名冲突。
- 用pandas的向量化操作,比循环遍历快得多,处理10000行毫无压力。
如果你坚持用拆分zone的思路(效率略低)
也可以实现,但不如第一种方法高效,代码示例:
# 创建字典存储每个zone的去重后数据 zone_dfs = {} for zone_val in df_a['zone'].unique(): # 取出当前zone的数据 temp_df = df_a[df_a['zone'] == zone_val] # 在当前zone内删除value重复的行(保留第一次出现的) temp_df = temp_df.loc[temp_df['value'].shift() != temp_df['value']] zone_dfs[zone_val] = temp_df # 把所有zone的数据合并,按原DataFrame的顺序排序 result = pd.concat(zone_dfs.values()).sort_index()
这个也能得到同样的结果,但处理大型数据集时,性能会比第一种方法差一些。
内容的提问来源于stack exchange,提问作者danwri
相关产品推荐
相关产品推荐

