来自 pandas 数据帧的 Select 行同时来自另一个数据帧中的行的两个值

Select rows from pandas dataframe by two values at the same time from rows in another dataframe

有关于pandas的问题:

我有两个数据框:

df1 = pd.DataFrame({'user_id': ['12', '22', '33', '44'],
                    'time': ['t1', 't2', 't3', 't4'],
                    'data': [{'av': '8.0', 'si': 3, 'am' : 2}, {'av': '8.0', 'si': 44}, {'av': '8.0', 'si': 1}, {'av': '8.0', 'si': 22}]})

df2 = pd.DataFrame({'user_id': ['11', '22', '33', '44'],
                    'time': ['t1', 't2', 't3', 't4'],
                    'data': [{'cv': 'ff', 'si': 3}, {'cv': 'ff', 'si': 44}, {'cv': 'fa', 'si': 2}, {'cv': 'ff', 'si': 21}]})

并且我需要过滤 df1 以拒绝包含值 'user_id' 和 ['data'] 的行。'si' 与 'user_id' 和 [[=29= 相同]].'si' 来自 df2 行。如果我愿意:

filter1 = df1['data'].str['si'].isin(df2['data'].str['si'])
filter2 = df1['user_id'].isin(df2['user_id'])
df3= df1[filter1 & filter2]

结果无效,因为我需要准确拒绝值满足两个条件的行: 例如 df1

中的第 2 行
user_id       time        data
  22           t2    'av': '8.0', 'si': 44

来自 df2:

user_id       time        data
  22           t2    'cv': 'ff', 'si': 44

非常感谢您的帮助!

规范化数据应该会简化此操作,并且每个潜在的比较都会变得更加容易和清晰。

标准化 + 应用清洁条件:

df1 = pd.concat([df1.drop(columns=['data']), pd.json_normalize(df1.data)], axis=1)
df2 = pd.concat([df2.drop(columns=['data']), pd.json_normalize(df2.data)], axis=1)

现在数据框如下所示:

df1:

user_id time av si am
0 12 t1 8 3 2
1 22 t2 8 44 nan
2 33 t3 8 1 nan
3 44 t4 8 22 nan

df2:

user_id time cv si
0 11 t1 ff 3
1 22 t2 ff 44
2 33 t3 fa 2
3 44 t4 ff 21

现在您可以将它们合并并使用指示器,如下所示

df1_filtered = df1.merge(df2[['user_id', 'si']], how='outer', indicator=True)
df1_filtered = df1_filtered[df1_filtered._merge.eq('left_only')].drop(columns=['_merge'])
df1_filtered
user_id time av si am
0 12 t1 8 3 2
2 33 t3 8 1 nan
3 44 t4 8 22 nan
df2_filtered = df2.merge(df1[['user_id', 'si']], how='outer', indicator=True)
df2_filtered = df2_filtered[df2_filtered._merge.eq('left_only')].drop(columns=['_merge'])
print(df2_filtered.to_markdown())
user_id time cv si
0 11 t1 ff 3
2 33 t3 fa 2
3 44 t4 ff 21