如何从两个单独的数据框中按日期查找不匹配的值?
我的数据框如下:
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
答案 0 :(得分:1)
append
和drop_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