Pandas 将 DataFrame 与基本事实 DataFrame 进行比较
Pandas comparing a DataFrame against a ground truth DataFrame
我有一个 DataFrame,其中包含 无序 项目 ID 及其各自负责人的列表。我想将新数据框的值与基本事实进行比较,以验证新数据框中的所有项目 ID 是否都是;在 ground truth 中并且有相同的领导者。有时,新的 DataFrame 可能有不同的列名,但它们总是两个,并且总是表示相同的东西。
例如ground truth DataFrame (df_gt):
Project ID Leader
123 Owen Wilson
122 Samuel Jackson
145 Jack Black
134 Natalie Portman
虽然新的 DataFrame 可能是 (df_new):
Project Leader
123 Owen Wilson
122 Henry Cavil
144 Natalie Portman
146 Jack Black
我想要的输出将是在新 DataFrame 中发现的与基本事实的所有偏差的列表。在这种情况下:
错误 == [[122,亨利·卡维尔],[144,娜塔莉·波特曼],[146,杰克·布莱克]]
最简单的方法是什么来容纳多个潜在的新数据框,每个数据框都有自己的列命名约定但具有相同的预期值。
df_1 = pd.DataFrame(data={'Project ID': [123, 122, 145, 134], 'Leader': ['Owen Wilson', 'Samuel Jackson',
'Jack Black', 'Natalie Portman']})
df_2 = pd.DataFrame(data={'Project ID': [123, 122, 144, 146], 'Leader': ['Owen Wilson', 'Henry Cavil',
'Natalie Portman', 'Jack Black']})
df_2['new'] = df_2['Project ID'].map(df_1.set_index('Project ID')['Leader'])
df_2 = df_2[(df_2['Leader']!=df_2['new'])]
print(df_2[['Project ID', 'Leader']].values.tolist())
假设数据帧总是有两列并且顺序与OP中提到的相同,我们可以使用MultiIndex.difference
找到不匹配的行
errs = pd.MultiIndex.from_frame(df_new)\
.difference(pd.MultiIndex.from_frame(df_gt))
>>> list(errs)
[(122, 'Henry Cavil'), (144, 'Natalie Portman'), (146, 'Jack Black')]
另一个解决方案是使用 .merge
和 indicator=
:
x = df1.merge(
df2,
left_on=["Project ID", "Leader"],
right_on=["Project", "Leader"],
indicator=True,
how="right",
)
errors = (
x.loc[x._merge.eq("right_only")]
.apply(lambda x: [x["Project"], x["Leader"]], axis=1)
.to_list()
)
print(errors)
打印:
[[122, 'Henry Cavil'], [144, 'Natalie Portman'], [146, 'Jack Black']]
我有一个 DataFrame,其中包含 无序 项目 ID 及其各自负责人的列表。我想将新数据框的值与基本事实进行比较,以验证新数据框中的所有项目 ID 是否都是;在 ground truth 中并且有相同的领导者。有时,新的 DataFrame 可能有不同的列名,但它们总是两个,并且总是表示相同的东西。
例如ground truth DataFrame (df_gt):
Project ID Leader
123 Owen Wilson
122 Samuel Jackson
145 Jack Black
134 Natalie Portman
虽然新的 DataFrame 可能是 (df_new):
Project Leader
123 Owen Wilson
122 Henry Cavil
144 Natalie Portman
146 Jack Black
我想要的输出将是在新 DataFrame 中发现的与基本事实的所有偏差的列表。在这种情况下:
错误 == [[122,亨利·卡维尔],[144,娜塔莉·波特曼],[146,杰克·布莱克]]
最简单的方法是什么来容纳多个潜在的新数据框,每个数据框都有自己的列命名约定但具有相同的预期值。
df_1 = pd.DataFrame(data={'Project ID': [123, 122, 145, 134], 'Leader': ['Owen Wilson', 'Samuel Jackson',
'Jack Black', 'Natalie Portman']})
df_2 = pd.DataFrame(data={'Project ID': [123, 122, 144, 146], 'Leader': ['Owen Wilson', 'Henry Cavil',
'Natalie Portman', 'Jack Black']})
df_2['new'] = df_2['Project ID'].map(df_1.set_index('Project ID')['Leader'])
df_2 = df_2[(df_2['Leader']!=df_2['new'])]
print(df_2[['Project ID', 'Leader']].values.tolist())
假设数据帧总是有两列并且顺序与OP中提到的相同,我们可以使用MultiIndex.difference
找到不匹配的行
errs = pd.MultiIndex.from_frame(df_new)\
.difference(pd.MultiIndex.from_frame(df_gt))
>>> list(errs)
[(122, 'Henry Cavil'), (144, 'Natalie Portman'), (146, 'Jack Black')]
另一个解决方案是使用 .merge
和 indicator=
:
x = df1.merge(
df2,
left_on=["Project ID", "Leader"],
right_on=["Project", "Leader"],
indicator=True,
how="right",
)
errors = (
x.loc[x._merge.eq("right_only")]
.apply(lambda x: [x["Project"], x["Leader"]], axis=1)
.to_list()
)
print(errors)
打印:
[[122, 'Henry Cavil'], [144, 'Natalie Portman'], [146, 'Jack Black']]