根据第二个数据框中的多列过滤数据 python

Filter data based on multiple columns in second dataframe python

我有一个包含多列的 Dataframe df1(原始 table)。

我有一个过滤后的 DataFrame df2,其中列 dateagent_idgps1gps2 只有 4 列。

df1 中,我有 dateagent_idfinal_gps 以及其他列。

我想过滤 df1 中存在于 df2 的所有数据,我想根据

进行比较

Df1.date == df2.date & df1.agent_id == df2.agent_id & (df1.final_gps == df2.gps1df1.final_gps == df2.gps2)

df2 样本

date       agent_id  gps1    gps2
14-02-2020  12abc   (1,2)   (7,6)
14-02-2020  12abc   (3,4)   (7,6)
14-02-2020  33bcd   (6,7)   (8,9)
20-02-2020  44hgf   (1,6)   (3,7)
20-02-2020  12abc   (3,5)   (3,1)
20-02-2020  33bcd   (3,4)   (3,6)
21-02-2020  12abc   (4,5)   (5,4)

df1 样本

date       agent_id final_gps   ….
10-02-2020  12abc   (1,2)       …
10-02-2020  33bcd   (8,9)       …
14-02-2020  12abc   (1,2)       …
14-02-2020  12abc   (7,6)       …
14-02-2020  12abc   (3,4)       …
14-02-2020  33bcd   (6,7)       …
14-02-2020  33bcd   (8,9)       …
14-02-2020  33bcd   (1,1)       …
14-02-2020  33bcd   (2,2)       …
18-02-2020  12abc   (1,2)       …
19-02-2020  44hgf   (6,7)       …
20-02-2020  12abc   (3,5)       …
20-02-2020  12abc   (3,1)       …
20-02-2020  44hgf   (1,6)       …
20-02-2020  44hgf   (3,7)       …

要求输出:-

date       agent_id final_gps   ….
14-02-2020  12abc   (1,2)       …
14-02-2020  12abc   (7,6)       …
14-02-2020  12abc   (3,4)       …
14-02-2020  33bcd   (6,7)       …
14-02-2020  33bcd   (8,9)       …
20-02-2020  12abc   (3,5)       …
20-02-2020  12abc   (3,1)       …
20-02-2020  44hgf   (1,6)       …
20-02-2020  44hgf   (3,7)       …

我试过了,但它给了我存在于 df2 中的所有匹配记录,但我只想要那些 agent_id 在特定 date 和特定 gps 匹配条件来自 df1.

df = df1[df1['date'].isin(df2['date']) & 
         df1['agent_id'].isin(df2['agent_id']) & 
        (df1['final_gps'].isin(df2['gps1']) | df1['final_gps'].isin(df2['gps2']))]

首先使用 DataFrame.meltgps1gps2 重塑为 final_gps,因此可能合并所有 3 列(无需定义 on),按所有列和最后排序删除重复项:

df = (df2.melt(id_vars=['date','agent_id'],
               value_vars=['gps1','gps2'],
               value_name='final_gps')
        .drop('variable', axis=1)
        .merge(df1)
        .drop_duplicates()
        .sort_values(by=['date','agent_id'], ignore_index=True))
print (df)
         date agent_id final_gps
0  14-02-2020    12abc     (1,2)
1  14-02-2020    12abc     (3,4)
2  14-02-2020    12abc     (7,6)
3  14-02-2020    33bcd     (6,7)
4  14-02-2020    33bcd     (8,9)
5  20-02-2020    12abc     (3,5)
6  20-02-2020    12abc     (3,1)
7  20-02-2020    44hgf     (1,6)
8  20-02-2020    44hgf     (3,7)

详情:

print (df2.melt(id_vars=['date','agent_id'],
               value_vars=['gps1','gps2'],
               value_name='final_gps'))

          date agent_id variable final_gps
0   14-02-2020    12abc     gps1     (1,2)
1   14-02-2020    12abc     gps1     (3,4)
2   14-02-2020    33bcd     gps1     (6,7)
3   20-02-2020    44hgf     gps1     (1,6)
4   20-02-2020    12abc     gps1     (3,5)
5   20-02-2020    33bcd     gps1     (3,4)
6   21-02-2020    12abc     gps1     (4,5)
7   14-02-2020    12abc     gps2     (7,6)
8   14-02-2020    12abc     gps2     (7,6)
9   14-02-2020    33bcd     gps2     (8,9)
10  20-02-2020    44hgf     gps2     (3,7)
11  20-02-2020    12abc     gps2     (3,1)
12  20-02-2020    33bcd     gps2     (3,6)
13  21-02-2020    12abc     gps2     (5,4)

您可以使用多个 isin 并使用 & 运算符将它们链接起来。由于 final_gps 可以是 gps1gps2,我们在括号中使用 | 运算符:

out = (df1[df1['date'].isin(df2['date']) & 
           df1['agent_id'].isin(df2['agent_id']) & 
           (df1['final_gps'].isin(df2['gps1']) | df1['final_gps'].isin(df2['gps2']))]
       .reset_index(drop=True))

输出:

         date agent_id final_gps ….
0  14-02-2020    12abc    (1, 2)  …
1  14-02-2020    12abc    (7, 6)  …
2  14-02-2020    12abc    (3, 4)  …
3  14-02-2020    33bcd    (6, 7)  …
4  14-02-2020    33bcd    (8, 9)  …
5  20-02-2020    12abc    (3, 5)  …
6  20-02-2020    12abc    (3, 1)  …
7  20-02-2020    44hgf    (1, 6)  …
8  20-02-2020    44hgf    (3, 7)  …