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

如何在Pandas中基于列c筛选,查找列a中大于当前行b值的最近前置值

问题:基于Pandas生成符合规则的列d

原始数据

import pandas as pd
df = pd.DataFrame({
    'a': [10, 20, 30, 1, 20, 3, 4, 0],
    'b': [30, 3, 11, 25, 24, 31, 29, 2],
    'c': [True, True, True, False, False, True, True, True]
})

期望输出

a   b      c    d
0  10  30   True    NaN
1  20   3   True    10
2  30  11   True    20
3   1  25  False    NaN
4  20  24  False    NaN
5   3  31   True    NaN
6   4  29   True    30
7   0   2   True    4

规则说明

  • 仅处理列c为True的行
  • 对目标行的b值,查找当前行之前所有行中,列a里大于该b值的最近一个值
  • 若列c为False,或没有符合条件的前置值,列d填NaN

原代码问题分析

你写的代码逻辑不符合需求:

import numpy as np
t = df['a'].to_numpy()
h = df['b'].to_numpy()

m2 = t < h[:, None]
df['d'] = np.nanmax(np.where(m2, t, np.nan), axis=1)

核心问题:

  1. np.nanmax取的是所有满足a > b的最大值,而不是时间上最近的那个值
  2. 没有过滤c=False的行,导致这些行也被错误计算

正确解法

方法1:使用apply逐行处理(代码简洁,适合中小数据量)

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'a': [10, 20, 30, 1, 20, 3, 4, 0],
    'b': [30, 3, 11, 25, 24, 31, 29, 2],
    'c': [True, True, True, False, False, True, True, True]
})

def get_recent_valid_a(row):
    if not row['c']:
        return np.nan
    # 截取当前行之前的所有行
    prev_rows = df.iloc[:row.name]
    # 筛选出a大于当前b的行
    valid_entries = prev_rows[prev_rows['a'] > row['b']]
    # 返回最后一个(最近的)a值,无则返回NaN
    return valid_entries['a'].iloc[-1] if not valid_entries.empty else np.nan

df['d'] = df.apply(get_recent_valid_a, axis=1)
print(df)

运行后输出与期望完全一致:

a   b      c     d
0  10  30   True   NaN
1  20   3   True  10.0
2  30  11   True  20.0
3   1  25  False   NaN
4  20  24  False   NaN
5   3  31   True   NaN
6   4  29   True  30.0
7   0   2   True   4.0

方法2:向量化遍历(效率更高,适合大数据量)

如果你的DataFrame行数很多,apply的效率会偏低,可以用循环只处理c=True的行:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'a': [10, 20, 30, 1, 20, 3, 4, 0],
    'b': [30, 3, 11, 25, 24, 31, 29, 2],
    'c': [True, True, True, False, False, True, True, True]
})

# 初始化d列为NaN
df['d'] = np.nan

# 筛选出需要处理的行索引
target_indices = df[df['c']].index

for idx in target_indices:
    # 取当前行之前的所有a值
    prev_a_values = df['a'].iloc[:idx]
    # 找到所有a > 当前b的索引
    valid_indices = prev_a_values[prev_a_values > df.loc[idx, 'b']].index
    if not valid_indices.empty:
        # 取最大的索引(最近的行)对应的a值
        df.loc[idx, 'd'] = df.loc[valid_indices.max(), 'a']

print(df)

内容的提问来源于stack exchange,提问作者AmirX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:08:10