如何用更高效且Pythonic的方式清理DataFrame,保留小于前值的元素
更高效、更Pythonic的数据集清理方案
嘿,你的这个数据集清理需求,其实用pandas内置的方法就能完美解决,而且比你现在的循环高效太多,代码也更简洁!
先拆解你的需求本质
你要的是:让序列里的每个元素,要么是自身(如果比前一个元素小),要么继承前一个元素的值(如果不小于)。换个角度看,这其实就是取序列到当前位置为止的累积最小值——因为累积最小值会自动“保留”之前的最小数值,当当前值不小于这个最小值时,就直接沿用它,完全匹配你的规则。
说说你现有代码的小问题
你的循环实现虽然能得到正确结果,但有两个可以优化的点:
- 直接通过
df_results['my_data'][data_idx[i]]修改元素,很可能触发pandas的SettingWithCopyWarning,这是官方不推荐的修改方式,容易引发意外的bug。 - Python循环在处理大数据集时速度很慢,而pandas的内置方法都是基于C扩展优化的,效率能提升好几个数量级。
一行代码搞定的最优方案
用pandas的cummin()方法,一行代码就能完成清理:
import pandas as pd # 初始化你的数据集 df_results = pd.DataFrame({'my_data': [10, 8, 7, 10, 5, 8, 2]}) # 计算累积最小值,直接替换原列 df_results['my_data'] = df_results['my_data'].cummin() # 查看结果 print(df_results)
运行后输出完全符合你的预期:
my_data 0 10 1 8 2 7 3 7 4 5 5 5 6 2
简单解释下原理
cummin()会逐行计算从序列开头到当前位置的最小值:
- 第0个元素:就是自身10
- 第1个元素:取
min(10, 8)得到8 - 第2个元素:取
min(10, 8, 7)得到7 - 第3个元素:取
min(10, 8, 7, 10)还是7 - 后面的元素以此类推,完美贴合你设定的清理规则。
这种方式不仅代码简洁易读,处理大规模数据时的速度优势会特别明显,绝对是更Pythonic的实现方式~
内容的提问来源于stack exchange,提问作者HennyKo
相关产品推荐
相关产品推荐

