使用一个pandas数据框的两列中的值过滤另一个数据框

7uzetpgm  于 2023-05-27  发布在  其他
关注(0)|答案(3)|浏览(174)

我有以下两个dataframe:
DF1

a1   b1         x        y
0  id1  1200.00    Meat     Client1
1  id2  240.20     Dairy    Client1
2  id3  -298.00    Veg      Client1
3  id4  10000.13   Fruit    Client3
4  id1  -569.13    Meat     Client2
5  id3  1000.00    Veg      Client5
6  id2  0.00       Dairy    Client1
7  id2  -32.00     Fruit    Client3

DF2

a2   b2         Category  
0  id1  1200.0013    1  
1  id2  -32.0115     4
2  id3  -298.0003    3 
3  id4  10000.1300   4

我想用以下方法过滤df1
1.列a1中的值来自df2中的列a2,以及
1.列b1,其中的值来自df2中的列b2(近似值,因为可能出现舍入误差)
这是我正在寻找的输出:
DF3

a2   b2         x       y
0  id1  1200.00    Meat    Client1
1  id2  -32.00     Fruit   Client3
2  id3  -298.00    Veg     Client1
3  id4  10000.13   Fruit   Client3

请指示。

qmelpv7a

qmelpv7a1#

可以使用merge_asof

df3 = (
    pd.merge_asof(
        df2.sort_values("b2"), df1.sort_values("b1"),
        left_on="b2", right_on="b1", left_by="a2", right_by="a1",
        direction="nearest")[["a2", "b2", "x", "y"]]
      .sort_values(by="a2", ignore_index=True)
)

输出:

print(df3)

    a2       b2      x        y
0  id1  1200.00   Meat  Client1
1  id2   -32.01  Fruit  Client3
2  id3  -298.00    Veg  Client1
3  id4 10000.13  Fruit  Client3
acruukt9

acruukt92#

这可以通过合并来完成,并且您可以使用舍入而不修改原始数据以获得近似匹配。

import pandas as pd
import numpy as np

# Adjust precision for approximation
DECIMAL_PRECISION = 1

# Your original dataframes
df1 = pd.DataFrame({
    'a1': ['id1', 'id2', 'id3', 'id4', 'id1', 'id3', 'id2', 'id2'],
    'b1': [1200.00, 240.20, -298.00, 10000.13, -569.13, 1000.00, 0.00, -32.00],
    'x': ['Meat', 'Dairy', 'Veg', 'Fruit', 'Meat', 'Veg', 'Dairy', 'Fruit'],
    'y': ['Client1', 'Client1', 'Client1', 'Client3', 'Client2', 'Client5', 'Client1', 'Client3']
})

df2 = pd.DataFrame({
    'a2': ['id1', 'id2', 'id3', 'id4'],
    'b2': [1200.0013, -32.0115, -298.0003, 10000.1300],
    'Category': [1, 4, 3, 4]
})

# Perform the filtering
df3 = df1.merge(df2, 
                left_on=['a1', np.round(df1['b1'], DECIMAL_PRECISION)], 
                right_on=['a2', np.round(df2['b2'], DECIMAL_PRECISION)], 
                how='inner')

# Select the desired columns in the output
df3 = df3[['a2', 'b2', 'x', 'y']].sort_values(by='a2')

print(df3)
## OUTPUTS
    a2          b2      x        y
0  id1   1200.0013   Meat  Client1
3  id2    -32.0115  Fruit  Client3
1  id3   -298.0003    Veg  Client1
2  id4  10000.1300  Fruit  Client3

编辑

到目前为止,我对这里介绍的所有方法进行了一个小的速度测试。他们都很接近,正如人们所料。

%%timeit
## Method 1:

# Perform the filtering
df3 = df1.merge(df2, 
                left_on=['a1', np.round(df1['b1'], DECIMAL_PRECISION)], 
                right_on=['a2', np.round(df2['b2'], DECIMAL_PRECISION)], 
                how='inner')

# Select the desired columns in the output
df3 = df3[['a2', 'b2', 'x', 'y']].sort_values(by='a2')

3.16 ms ± 696 µs/循环(平均值±标准运行7次,每次循环100次)

%%timeit
## Method 2:

df3 = (
    pd.merge_asof(
        df2.sort_values("b2"), df1.sort_values("b1"),
        left_on="b2", right_on="b1", left_by="a2", right_by="a1",
        direction="nearest")[["a2", "b2", "x", "y"]]
      .sort_values(by="a2", ignore_index=True)
)

3.65 ms ± 1.07 ms/循环(平均值±标准差)运行7次,每次循环100次)

%%timeit
## Method 3:

df3 = pd.merge(
    df1.assign(b1 = df1['b1'].round(0)).rename({'a1':'a2','b1':'b2'},axis=1),
    df2.assign(b2 = df2['b2'].round(0)),
    on = ['a2','b2']).sort_values(by='a2')

3.23 ms ± 427 µs/循环(平均值±标准值运行7次,每次循环100次)

l0oc07j2

l0oc07j23#

这里有一个选项,它在合并之前对值进行四舍五入。

df3 = pd.merge(
    df1.assign(b1 = df1['b1'].round(0)).rename({'a1':'a2','b1':'b2'},axis=1),
    df2.assign(b2 = df2['b2'].round(0)),
    on = ['a2','b2'])

输出:

a2       b2      x        y  Category
0  id1   1200.0   Meat  Client1         1
1  id3   -298.0    Veg  Client1         3
2  id4  10000.0  Fruit  Client3         4
3  id2    -32.0  Fruit  Client3         4

相关问题