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

如何在Python中匹配两个DataFrame的最相似行(基于金额与日期)

无匹配ID的DataFrame行匹配需求

需要在两个无匹配ID的DataFrame中,为每行找到最相似的对应行,通过比较Amount、Ocurred Date、Sale Date三列的相近值(最接近的金额与日期)实现匹配。

Df1数据

IDAmountOcurred DateSale Date
1$10002/20/202302/20/2022
2$2001/20/202308/19/2022

Df2数据

ID2AmountOcurred DateSale Date
9$9802/20/202302/21/2022
8$1901/19/202308/23/2022

预期输出

IDID2
19
28

实现方案(Python + Pandas)

1. 数据预处理

要计算相似度,首先得把数据转成可计算的格式:

  • 金额列去掉$符号,转成数值类型;
  • 日期列转成datetime类型,方便计算天数差。

代码如下:

import pandas as pd

# 构造示例数据
df1 = pd.DataFrame({
    'ID': [1, 2],
    'Amount': ['$100', '$20'],
    'Ocurred Date': ['02/20/2023', '01/20/2023'],
    'Sale Date': ['02/20/2022', '08/19/2022']
})

df2 = pd.DataFrame({
    'ID2': [9, 8],
    'Amount': ['$98', '$19'],
    'Ocurred Date': ['02/20/2023', '01/19/2023'],
    'Sale Date': ['02/21/2022', '08/23/2022']
})

# 清洗金额列
df1['Amount'] = df1['Amount'].str.replace('$', '').astype(float)
df2['Amount'] = df2['Amount'].str.replace('$', '').astype(float)

# 转换日期格式
date_format = '%m/%d/%Y'
df1['Ocurred Date'] = pd.to_datetime(df1['Ocurred Date'], format=date_format)
df1['Sale Date'] = pd.to_datetime(df1['Sale Date'], format=date_format)
df2['Ocurred Date'] = pd.to_datetime(df2['Ocurred Date'], format=date_format)
df2['Sale Date'] = pd.to_datetime(df2['Sale Date'], format=date_format)

2. 匹配最相似行

我们通过计算金额差值绝对值、发生日期天数差绝对值、销售日期天数差绝对值的加权和来衡量相似度——加权和越小,两行越相似。为df1的每行找到df2中加权和最小的行即可:

def get_best_match(row, target_df):
    # 计算各项差异值
    amount_diff = abs(row['Amount'] - target_df['Amount'])
    ocurred_day_diff = abs((row['Ocurred Date'] - target_df['Ocurred Date']).dt.days)
    sale_day_diff = abs((row['Sale Date'] - target_df['Sale Date']).dt.days)
    
    # 加权计算总差异(权重可根据业务优先级调整)
    total_diff = amount_diff * 0.5 + ocurred_day_diff * 0.3 + sale_day_diff * 0.2
    
    # 返回差异最小的行的ID2
    return target_df.loc[total_diff.idxmin(), 'ID2']

# 为df1每行匹配对应的ID2
df1['ID2'] = df1.apply(get_best_match, target_df=df2, axis=1)

# 提取需要的结果列
match_result = df1[['ID', 'ID2']]
print(match_result)

运行结果

ID  ID2
0   1    9
1   2    8

补充说明

  • 权重可以按需调整:比如如果金额匹配优先级最高,可以把金额的权重调至0.7,日期权重相应降低;
  • 若数据量很大,逐行计算的效率偏低,可以用sklearn.neighbors.NearestNeighbors这类KNN算法来优化匹配速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:44:56