仅当单独列中的差异在[n,+n]范围内时,才在公共列上连接两个数据帧

2024-09-30 01:20:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数据帧df1df2,如下所示:

df1

Date        BillNo.     Amount
10/08/2020  ABBCSQ1ZA   878
10/09/2020  AADC9C1Z5   11
10/12/2020  AC928Q1ZS   3998
10/14/2020  AC9268RE3   198
10/16/2020  AA171E1Z0   5490
10/19/2020  BU073C1ZW   3432

df2

Date        BillNo.     Amount
10/08/2020  ABBCSQ1ZA   876
10/11/2020  ATRC95REW   115
10/14/2020  AC9268RE3   212
10/16/2020  AA171E1Z0   5491
10/25/2020  BPO66W2LO   344

我的最后答案应该是:

final

Date        BillNo.     Amount
10/08/2020  ABBCSQ1ZA   876
10/16/2020  AA171E1Z0   5491

当值范围的差异在[-5,5]之间时,如何使用Date BillNo. Amount从两个数据帧中查找公共行

我知道如何使用以下命令查找公用行:

df_all = df1.merge(df2.drop_duplicates(), on=['Date', 'BillNo.', 'Amount'], 
                   how='outer', indicator=True)

但是,这不会给出范围内的行。有人能帮忙吗

编辑:我们可以在df1: 10/14/2020,AC9268RE3,198df2: 10/14/2020,AC9268RE3,212中看到差异是14,因此这不应该包含在公共行中


Tags: 数据date差异amountdf1df2ac928q1zsatrc95rew
3条回答

我们可以合并,然后执行查询以删除不在范围内的行:

(df1.merge(df2, on=['Date', 'BillNo.'])
    .query('abs(Amount_x - Amount_y) <= 5')
    .drop('Amount_x', axis=1))

         Date    BillNo.  Amount_y
0  10/08/2020  ABBCSQ1ZA       876
1  10/16/2020  AA171E1Z0      5491

只要在每个帧中只有一行对应于特定的(日期,BillNo)组合,这种方法就可以很好地工作

我们可以设置DateBillNo.作为索引,同时减去数据帧,并仅过滤出值b/w-5到5

d1 = df1.set_index(['Date', 'BillNo.'])
d2 = df2.set_index(['Date', 'BillNo.'])

idx = (d1-d2).query('Amount>=-5 & Amount<=5').index

d1.loc[idx].reset_index()
         Date    BillNo.  Amount
0  10/08/2020  ABBCSQ1ZA     878
1  10/16/2020  AA171E1Z0    5490

d2.loc[idx].reset_index()
         Date    BillNo.  Amount
0  10/08/2020  ABBCSQ1ZA     876
1  10/16/2020  AA171E1Z0    5491

使其更通用于任何n

n = 5
idx = (d1-d2).query('Amount>=-@n & Amount<=@n').index

lower_limit = -2 # Example, can be anything
upper_limit = 5  # Example, can be anything
idx = (d1-d2).query('Amount>=@lower_limit & Amount<=@upper_limit').index

您可以使用merge_asof

udf2 = df2.drop_duplicates().sort_values('Amount')
res = pd.merge_asof(udf2, df1.sort_values('Amount').assign(indicator=1), on='Amount', by=['Date', 'BillNo.'],
                    direction='nearest', tolerance=5)
res = res.dropna().drop('indicator', 1)

print(res)

输出

         Date    BillNo.  Amount
2  10/08/2020  ABBCSQ1ZA     876
3  10/16/2020  AA171E1Z0    5491

相关问题 更多 >

    热门问题