如何对比DataFrame列前后行浮点值并筛选符合条件的行
解决方案
高效实现:利用Pandas内置方法避免循环报错
直接使用Pandas的shift()方法处理行与行的对比,比for循环更高效且不会出现索引越界等报错问题。以下是满足需求的函数:
import pandas as pd def filter_target_rows(df, col_name, compare_first, compare_last): # 复制原数据,避免修改原DataFrame filtered_df = df.copy() # 获取前一行和后一行的对应列值 prev_vals = filtered_df[col_name].shift(1) next_vals = filtered_df[col_name].shift(-1) # 替换首尾行的对比值 prev_vals.iloc[0] = compare_first # 首行的"前一行"用自定义值代替 next_vals.iloc[-1] = compare_last # 末行的"后一行"用自定义值代替 # 定义你指定的两个筛选条件 cond1 = (filtered_df[col_name] < prev_vals) & (filtered_df[col_name] > next_vals) cond2 = (filtered_df[col_name] > prev_vals) & (filtered_df[col_name] < next_vals) # 筛选符合任一条件的行 result = filtered_df[cond1 | cond2] return result
针对示例数据的修正说明
注意:根据你给出的条件描述,示例数据中的b、e、f行并不满足条件(比如b行的2.0同时小于前一行5.5和后一行2.5,不符合你列出的两个条件)。如果你的实际需求是筛选局部极值(局部最大值/最小值)(对应你给出的期望输出),可以修改函数内的条件为:
# 修改后的条件:筛选局部最小值和局部最大值 cond_min = (filtered_df[col_name] < prev_vals) & (filtered_df[col_name] < next_vals) cond_max = (filtered_df[col_name] > prev_vals) & (filtered_df[col_name] > next_vals) result = filtered_df[cond_min | cond_max]
用这个修改后的条件测试你的示例数据:
values = [[5.5, 2.5, 10.0], [2.0, 4.5, 1.0], [2.5, 5.2, 8.0], [4.5, 5.8, 4.8], [4.6, 6.3, 9.6], [4.1, 6.4, 9.0], [5.1, 2.3, 11.1]] a_df = pd.DataFrame(values, columns=['col1', 'col2', 'col3'], index=['a', 'b', 'c', 'd', 'e', 'f', 'g']) # 调用函数,首尾行自定义对比值可根据需求设置,这里用远大于极值的数值 output = filter_target_rows(a_df, 'col1', compare_first=100, compare_last=100) print(output)
输出结果将完全匹配你给出的期望:
col1 col2 col3 b 2.0 4.5 1.0 e 4.6 6.3 9.6 f 4.1 6.4 9.0
为什么不用for循环?
Pandas的向量化操作(如shift())是基于底层优化实现的,不仅比for循环快得多,还能避免手动遍历时常出现的索引越界、类型不匹配等报错问题,代码可读性也更强。
内容的提问来源于stack exchange,提问作者DataScientistNovice
相关产品推荐
相关产品推荐

