如何从两个单独的数据框中按日期查找不匹配的值?

时间:2019-06-05 20:07:27

标签: python-3.x pandas

如何从两个单独的数据框中按日期查找不匹配的值?

我的数据框如下:

import pandas as pd

data_1 = {'date':['2019-05-01','2019-05-02'],
          'id': ['1122','1133']}
data_2 = {'id': ['1122','1133','1144']}

df1 = pd.DataFrame(data_1, columns=['date','id'])
df2 = pd.DataFrame(data_2, columns=['id'])

我需要的结果是一个数据框,其中包含df2中与df1不匹配的任何ID和df1中的日期。

所以结果应该看起来像

   date     id
2019-05-01 1133
2019-05-01 1144
2019-05-02 1122
2019-05-02 1144

3 个答案:

答案 0 :(得分:1)

appenddrop_duplicates

创建一个起始数据帧,该数据帧由df1中的日期和df2中的id组成。

d = pd.DataFrame([
    [d, i] for d in df1.date
    for i in df2.id
], columns=df1.columns)

d.append(df1).drop_duplicates(keep=False)

         date    id
1  2019-05-01  1133
2  2019-05-01  1144
3  2019-05-02  1122
5  2019-05-02  1144

或者我们可以在构建步骤中跳过现有的

tups = {*zip(*map(df1.get, df1))}
pd.DataFrame([
    [d, i] for d in df1.date
    for i in df2.id if (d, i) not in tups
], columns=df1.columns)

         date    id
0  2019-05-01  1133
1  2019-05-01  1144
2  2019-05-02  1122
3  2019-05-02  1144

或使用itertools.product和某些set逻辑

顺便说一句我的最爱!

from itertools import product

pd.DataFrame(
    {*product(df1.date, df2.id)} - {*zip(*map(df1.get, df1))},
    columns=df1.columns
)

         date    id
0  2019-05-01  1144
1  2019-05-01  1133
2  2019-05-02  1144
3  2019-05-02  1122

答案 1 :(得分:1)

这更像是带有过滤器的CJ(交叉联接)问题

df1.assign(key=1).merge(df2.assign(key=1),on='key').loc[lambda x : x['id_x']!=x['id_y']].drop(['key','id_x'],1)
Out[262]: 
         date  id_y
1  2019-05-01  1133
2  2019-05-01  1144
3  2019-05-02  1122
5  2019-05-02  1144

答案 2 :(得分:0)

尝试:

# first we change `df1.id` to columns by crosstab:
u = pd.crosstab(df1.date, df1.id)

# extend the id with df2.id
u = u.reindex(df2['id'], axis=1, fill_value=0).stack()

那么您正在寻找的是

u[u.eq(0)].index.to_frame().reset_index(drop=True)

输出:

          date  id
0   2019-05-01  1133
1   2019-05-01  1144
2   2019-05-02  1122
3   2019-05-02  1144