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

如何在Python Pandas中基于多匹配条件合并DataFrame并添加状态字段、过滤不匹配记录

Solution to Merge DataFrames with Multiple Matching Conditions

First, let's set up our sample DataFrames exactly as provided:

import pandas as pd

# Original df1
df1 = pd.DataFrame({
    'id': [1, 2, 3, 4],
    'user_id': [1, 2, 3, 4],
    'name': ['John', 'Alves', 'Kristein', 'James'],
    'email': ['John@example.com', 'alves@example.com', 'kristein@example.com', 'james@example.com']
})

# Original df2
df2 = pd.DataFrame({
    'id': [1, 2, 3, 4],
    'user': ['Sanders', 'Alves', 'Micheal', 'James'],
    'user_email_1': ['sanders@example.com', 'alves111@example.com', 'micheal@example.com', 'james@example.com'],
    'user_email_2': ['', 'alves@example.com', '', ''],
    'status': ['active', 'active', 'active', 'delete']
})

Approach 1: Using apply() for Simple Readability

This method is straightforward and easy to follow, ideal for smaller datasets. We'll define a function that checks each of your three conditions for every row in df1, then assign the matching status and drop any unmatched rows.

def get_matching_status(row):
    # Check Condition 1: user_id matches df2's id
    cond1_match = df2[df2['id'] == row['user_id']]
    if not cond1_match.empty:
        return cond1_match['status'].iloc[0]
    
    # Check Condition 2: name matches df2's user
    cond2_match = df2[df2['user'] == row['name']]
    if not cond2_match.empty:
        return cond2_match['status'].iloc[0]
    
    # Check Condition 3: email matches either user_email_1 or user_email_2 in df2
    cond3_match = df2[(df2['user_email_1'] == row['email']) | (df2['user_email_2'] == row['email'])]
    if not cond3_match.empty:
        return cond3_match['status'].iloc[0]
    
    # No match found
    return None

# Apply the function to each row in df1
df1['status'] = df1.apply(get_matching_status, axis=1)

# Drop rows with no matching status and reset index
df1 = df1.dropna(subset=['status']).reset_index(drop=True)

print(df1)

Output:

id  user_id   name               email  status
0   2        2  Alves  alves@example.com   active
1   4        4  James  james@example.com   delete

Approach 2: Vectorized Merges for Performance

If you're working with large datasets, this vectorized approach is far more efficient. We'll merge on each condition separately, then combine the results to get the final status.

# Merge on Condition 1: user_id == df2.id
merge_cond1 = df1.merge(df2[['id', 'status']], left_on='user_id', right_on='id', how='left', suffixes=('', '_cond1'))
merge_cond1 = merge_cond1.drop(columns=['id_cond1'])

# Merge on Condition 2: name == df2.user
merge_cond2 = merge_cond1.merge(df2[['user', 'status']], left_on='name', right_on='user', how='left', suffixes=('', '_cond2'))
merge_cond2 = merge_cond2.drop(columns=['user'])

# Create a temp DataFrame for email matches (both user_email_1 and user_email_2)
email_matches = pd.concat([
    df2[['user_email_1', 'status']].rename(columns={'user_email_1': 'email'}),
    df2[['user_email_2', 'status']].rename(columns={'user_email_2': 'email'})
])
email_matches = email_matches[email_matches['email'] != '']  # Remove empty email entries

# Merge on Condition 3: email matches either email column
merge_cond3 = merge_cond2.merge(email_matches, on='email', how='left', suffixes=('', '_cond3'))

# Combine status columns: take the first non-null status from any condition
merge_cond3['status'] = merge_cond3[['status_cond1', 'status_cond2', 'status_cond3']].bfill(axis=1).iloc[:, 0]

# Clean up: drop extra columns and unmatched rows
final_df = merge_cond3.drop(columns=['status_cond1', 'status_cond2', 'status_cond3']).dropna(subset=['status']).reset_index(drop=True)

print(final_df)

This produces the exact same result as Approach 1, but leverages pandas' optimized vector operations to handle large datasets much faster than row-wise apply().

Both methods correctly match Alves (via name and email) and James (via name and email), while dropping John and Kristein who have no matches in df2.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:02:35