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

如何结合对应位置条件同时遍历两个DataFrame并筛选数据?

筛选符合条件的DataFrame行

我有两个DataFrame,需求是:遍历第一个DataFrame(df1),当其中元素满足以'XY'开头的条件时,检查第二个DataFrame(df2)对应行列位置的日期是否早于'2003-01-01';最终保留df1中所有以'XY'开头的元素对应的df2日期都不早于2003-01-01的行。

df1结构

id123
0XY00AB80XY01
1FY34XY60XY91
2AB46AC40NY23
3XY70AB23DG60

df2结构(与df1行索引对应,列名不同但位置匹配)

ide1e2e3
02003-12-092005-01-012006-12-14
12004-11-092002-01-011999-07-10
22012-02-132011-08-222003-03-16
32003-01-172005-01-012017-09-30

理想输出

id123
0XY00AB80XY01
3XY70AB23DG60

我的错误代码(输出空DataFrame)

new_df = pd.DataFrame(data = None, columns = df1.columns)

for ind, row in df1.iterrows():
    if ((ind,row) == ("XY00")):
        for ind2, row2 in df2.iterrows():
             if((ind2,row2) >= ("2003-01-01")):
                    new_df = new_df.append(row)

错误原因分析

  1. 判断逻辑完全错误:(ind,row) == ("XY00")中,ind是行索引(如0、1),row是整行数据的Series,不可能等于单个字符串"XY00",根本无法触发后续逻辑。
  2. 不必要的嵌套遍历:df1和df2行索引一一对应,无需重新遍历df2所有行,直接通过索引取对应行即可。
  3. 条件与需求相悖:需求是检查日期是否早于2003-01-01,代码中写的是>=,且未将日期转为datetime类型,虽然字符串格式可比较,但不够严谨。
  4. 未处理列对应关系:df1的列是1、2、3,df2的是e1、e2、e3,代码未建立对应映射,无法匹配正确位置。

正确解决方案

方法1:向量化操作(推荐,pandas最优实践)

利用pandas的向量化运算,避免低效循环:

import pandas as pd

# 将df2的日期列转为datetime类型
df2 = df2.apply(pd.to_datetime)
# 定义目标日期
target_date = pd.to_datetime('2003-01-01')

# 建立列映射关系
col_map = {'1': 'e1', '2': 'e2', '3': 'e3'}
# 生成布尔掩码:标记每行是否存在「XY开头元素且对应日期早于目标日期」的情况
mask = ~(
    (df1[col_map.keys()].apply(lambda x: x.str.startswith('XY'))) & 
    (df2[col_map.values()] < target_date)
).any(axis=1)

# 筛选符合条件的行
new_df = df1[mask]
print(new_df)

方法2:修正后的循环方法(贴合原思路)

如果坚持用循环,修正逻辑如下:

import pandas as pd

new_df = pd.DataFrame(columns=df1.columns)
target_date = pd.to_datetime('2003-01-01')
# 转换df2日期类型
df2 = df2.apply(pd.to_datetime)
# 列对应映射
col_map = {'1': 'e1', '2': 'e2', '3': 'e3'}

for ind, row in df1.iterrows():
    keep_row = True
    # 获取df2对应行数据
    df2_row = df2.loc[ind]
    # 遍历需要检查的列
    for df1_col, df2_col in col_map.items():
        val = row[df1_col]
        if val.startswith('XY'):
            # 检查对应日期是否早于目标日期
            if df2_row[df2_col] < target_date:
                keep_row = False
                break  # 只要有一个不符合,直接终止当前行检查
    if keep_row:
        # 将符合条件的行添加到新DataFrame
        new_df = pd.concat([new_df, row.to_frame().T], ignore_index=True)

print(new_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:35:17