Pandas:使用 isin() 检查其他数据框中是否存在数据框观察的问题
Pandas: Issue using isin() to check if data frame observations exist in other dataframe
我有 df1:
trip_id latitude longitude datetime
0 356a192b7913b04c54574d18c28d46e6395428ab 57.723610 11.925191 2021-06-13 14:22:11.682
1 356a192b7913b04c54574d18c28d46e6395428ab 57.723614 11.925187 2021-06-13 14:22:13.562
2 356a192b7913b04c54574d18c28d46e6395428ab 57.723610 11.925172 2021-06-13 14:22:28.635
3 da4b9237bacccdf19c0760cab7aec4a8359010b0 57.723637 11.925056 2021-06-13 14:22:59.336
4 da4b9237bacccdf19c0760cab7aec4a8359010b0 57.724075 11.923708 2021-06-13 14:23:44.905
5 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723610 11.925191 2021-06-13 14:22:04.000
6 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723614 11.925178 2021-06-13 14:22:44.170
7 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723827 11.924635 2021-06-13 14:23:14.479
8 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723866 11.924005 2021-06-13 14:23:29.605
和 df2:
trip_id latitude longitude datetime
0 356a192b7913b04c54574d18c28d46e6395428ab 47.723610 14.925187 2021-06-13 14:22:59.336
1 555a192b7913b04c54574d18c28d46e639542yyy 60.723610 12.925187 2021-06-13 14:22:59.336
2 77de68daecd823babbb58edb1c8e14d7106e83cc 58.993066 13.924005 2022-06-13 20:23:29.605
我想检查 df2 中的行是否存在于 df1 中。为此,我尝试了:
df2.isin(df1)
>>
trip_id latitude longitude datetime
0 True False False False
1 False False False False
2 False False False False
最终目标是将 df2 中的观察结果(行)添加到 df1(如果它们不存在)。但是,由于 trip_id 中的索引 0 返回 True,因此不会将 df2 的整个第一行标识为 df1 中的新行。只要在观察中有一个元素不同,就应该在 df1 中添加一个新行。
要将 df2 中的新行添加到 df1,我会使用:
df3 = df1.append(df2, ignore_index=True)
所以最终,最终的代码应该是:
if df2.isin(df1):
df3 = df1.append(df2, ignore_index=True)
您只需 append
和 drop_duplicates
即可满足您的需求:
df1.append(df2).drop_duplicates()
您的示例数据有点混乱,您想拒绝 df2
中的重复项,但 df1
已经有重复项(由 trip_id
);例如df1
的前 3 行具有相同的 trip_id
。所以目标有点不清楚
此外,您期望的构造:
if df2.isin(df1):
df3 = df1.append(df2, ignore_index=True)
错了。正如您的示例所示,pd.DataFrame.isin
将 return 布尔数据框,并且未定义 pandas/numpy 数组的真值。您将收到此错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()
所以按照这个描述:
As long as there is one element different in the observations, it should be added as a new row in df1.
我建议如下:
df1.append(df2[~df1.isin(df2).all(axis=1)])
但是,如果您多次这样做,我建议您将代码重构为执行如下操作:
updates = [df2[...], df3[...], ..., dfn[...]]
result = pd.concat([df1, *updates]], axis=0)
我有 df1:
trip_id latitude longitude datetime
0 356a192b7913b04c54574d18c28d46e6395428ab 57.723610 11.925191 2021-06-13 14:22:11.682
1 356a192b7913b04c54574d18c28d46e6395428ab 57.723614 11.925187 2021-06-13 14:22:13.562
2 356a192b7913b04c54574d18c28d46e6395428ab 57.723610 11.925172 2021-06-13 14:22:28.635
3 da4b9237bacccdf19c0760cab7aec4a8359010b0 57.723637 11.925056 2021-06-13 14:22:59.336
4 da4b9237bacccdf19c0760cab7aec4a8359010b0 57.724075 11.923708 2021-06-13 14:23:44.905
5 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723610 11.925191 2021-06-13 14:22:04.000
6 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723614 11.925178 2021-06-13 14:22:44.170
7 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723827 11.924635 2021-06-13 14:23:14.479
8 77de68daecd823babbb58edb1c8e14d7106e83bb 57.723866 11.924005 2021-06-13 14:23:29.605
和 df2:
trip_id latitude longitude datetime
0 356a192b7913b04c54574d18c28d46e6395428ab 47.723610 14.925187 2021-06-13 14:22:59.336
1 555a192b7913b04c54574d18c28d46e639542yyy 60.723610 12.925187 2021-06-13 14:22:59.336
2 77de68daecd823babbb58edb1c8e14d7106e83cc 58.993066 13.924005 2022-06-13 20:23:29.605
我想检查 df2 中的行是否存在于 df1 中。为此,我尝试了:
df2.isin(df1)
>>
trip_id latitude longitude datetime
0 True False False False
1 False False False False
2 False False False False
最终目标是将 df2 中的观察结果(行)添加到 df1(如果它们不存在)。但是,由于 trip_id 中的索引 0 返回 True,因此不会将 df2 的整个第一行标识为 df1 中的新行。只要在观察中有一个元素不同,就应该在 df1 中添加一个新行。
要将 df2 中的新行添加到 df1,我会使用:
df3 = df1.append(df2, ignore_index=True)
所以最终,最终的代码应该是:
if df2.isin(df1):
df3 = df1.append(df2, ignore_index=True)
您只需 append
和 drop_duplicates
即可满足您的需求:
df1.append(df2).drop_duplicates()
您的示例数据有点混乱,您想拒绝 df2
中的重复项,但 df1
已经有重复项(由 trip_id
);例如df1
的前 3 行具有相同的 trip_id
。所以目标有点不清楚
此外,您期望的构造:
if df2.isin(df1):
df3 = df1.append(df2, ignore_index=True)
错了。正如您的示例所示,pd.DataFrame.isin
将 return 布尔数据框,并且未定义 pandas/numpy 数组的真值。您将收到此错误:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()
所以按照这个描述:
As long as there is one element different in the observations, it should be added as a new row in df1.
我建议如下:
df1.append(df2[~df1.isin(df2).all(axis=1)])
但是,如果您多次这样做,我建议您将代码重构为执行如下操作:
updates = [df2[...], df3[...], ..., dfn[...]]
result = pd.concat([df1, *updates]], axis=0)