You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对比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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:00:54