为 Pandas 中与合并不匹配的每一行创建一行

Create a row for each row that doesnt match a merge in Pandas

我有一个数据框:

  uses = pd.DataFrame({'person_id': [1, 2, 3], 'loop_id': [1, 1, 1], 'another_column': ['Hello', 'Hi', 'Hello']})
  loop_merge = pd.DataFrame({'loop_id': [1, 2], 'description': ['foo', 'bar']})

我想像 pd.merge(uses, loop_merge, on='loop_id') 那样合并,然后在我想要一个像这样的数据框之后:

person_id another_column loop_id description
1 Hello 1 foo
1 None 2 bar
2 Hi 1 foo
2 None 2 bar
3 Hello 1 foo
3 None 2 bar

所以我真正想要的是合并两个数据框,并且 loop_id 不匹配的地方我想为那个人创建一行(another_column 中缺少的数据)。谁能帮帮我?

从 pandas 1.2.0. 开始,您可以 cross merge。然后使用布尔掩码,将 NaN 值分配给行 loop_ids 上的“another_column”不匹配:

merged_df = uses.merge(loop_merge, how='cross', suffixes=('_',''))
merged_df.loc[merged_df['loop_id_']!=merged_df['loop_id'], 'another_column'] = np.nan
merged_df.drop('loop_id_', axis=1, inplace=True)

输出:

   person_id another_column  loop_id description
0          1          Hello        1         foo
1          1            NaN        2         bar
2          2             Hi        1         foo
3          2            NaN        2         bar
4          3          Hello        1         foo
5          3            NaN        2         bar

我自己找到了答案。我的问题的解决方案是为每个人创建另一个包含所有可能性的数据框,因此我必须只在 person_id 和 loop_merge 数据框之间进行交叉合并。之后,我只需要将这个新数据框与 how="left" 和 on=["person_id", "loop_id"].

的 uses 数据框合并
df_aux = pd.merge(uses[["person_id"]], loop_merge, how="cross")

df_wanted = pd.merge(df_aux, uses, how="left", on=["person_id", "loop_id"])

这给了我 loop_merge 和所有人 loop_id 的所有可能性。所以我将有多个行用于由人完成的循环,如果他们已经完成多次,并且不匹配的行将具有 NaN 列,这意味着该人没有执行该循环。

我希望这对外面的人有所帮助。