如何有效地找到两个具有 pandas 的大型数据帧之间的逆交集?
How to efficiently find the inverse intersection between two large dataframes with pandas?
我试图找到两个 large 数据帧之间的逆交集。
我得到它与此后剪断的代码一起工作。不幸的是,这种方法在大型数据帧上“太慢了”,如下所述。你能想出一种更快的方法来计算这个结果吗?
import pandas as pd
df_1 = pd.DataFrame({'a': [8, 2, 2],
'b': [0, 1, 3],
'c': [0, 2, 2],
'd': [0, 2, 2],
'e': [0, 2, 2]})
df_2 = pd.DataFrame({'a': [8, 2, 2, 2, 8, 2],
'b': [0, 1, 1, 6, 0, 1],
'c': [0, 3, 2, 2, 0, 2],
'd': [0, 4, 2, 2, 0, 4],
'e': [0, 1, 2, 2, 0, 2]})
l_columns = ['a','b','e']
def df_drop_df(df_1, df_2, l_columns):
"""
Eliminates all equal rows present in dataframe 1 (df_1) from dataframe 2 (df_2) depending on a subset of columns (l_columns)
:param df_1: dataframe that defines which rows to be removed
:param df_2: dataframe that is reduced
:param l_columns: list of column names, present in df_1 and df_2, that is used for the comparison
:return df_out: final dataframe
"""
df_1r = df_1[l_columns]
df_2r = df_2[l_columns].reset_index()
df_m = pd.merge(df_1r, df_2r, on=l_columns, how='inner')
row_indexes_m = df_m['index'].to_list()
row_indexes_df_2 = df_2.index.to_list()
row_indexes_out = [x for x in row_indexes_df_2 if x not in row_indexes_m]
df_out = df_2.loc[row_indexes_out]
return df_out
给出以下正确结果:
#row_indexes_out = [1,3]
df_output = df_drop_df(df_1, df_2, l_columns)
df_output
({'a': [2, 2],
'b': [1, 6],
'c': [3, 2],
'd': [4, 2],
'e': [1, 2]})
然而,对于实际应用,数据帧的大小具有以下尺寸,在我的本地计算机上大约需要 30 分钟来计算:
variable
shape
df1
(3300,77)
df2
(642000,77)
l_columns
list 12
df_out
(611000,77)
(这意味着 df_1 中出现的每一行大约是 df_2 中的 10 次)
你能想出一个更快的方法来计算这个结果吗?
您可以尝试替换为以下几行:
row_indexes_df_2 = df_2.index.to_list()
row_indexes_out = [x for x in row_indexes_df_2 if x not in row_indexes_m]
df_out = df_2.loc[row_indexes_out]
波浪号运算符:
df_out = df_2.loc[~df_2.index.isin(row_indexes_m)]
应该会大大减少时间。
我试图找到两个 large 数据帧之间的逆交集。 我得到它与此后剪断的代码一起工作。不幸的是,这种方法在大型数据帧上“太慢了”,如下所述。你能想出一种更快的方法来计算这个结果吗?
import pandas as pd
df_1 = pd.DataFrame({'a': [8, 2, 2],
'b': [0, 1, 3],
'c': [0, 2, 2],
'd': [0, 2, 2],
'e': [0, 2, 2]})
df_2 = pd.DataFrame({'a': [8, 2, 2, 2, 8, 2],
'b': [0, 1, 1, 6, 0, 1],
'c': [0, 3, 2, 2, 0, 2],
'd': [0, 4, 2, 2, 0, 4],
'e': [0, 1, 2, 2, 0, 2]})
l_columns = ['a','b','e']
def df_drop_df(df_1, df_2, l_columns):
"""
Eliminates all equal rows present in dataframe 1 (df_1) from dataframe 2 (df_2) depending on a subset of columns (l_columns)
:param df_1: dataframe that defines which rows to be removed
:param df_2: dataframe that is reduced
:param l_columns: list of column names, present in df_1 and df_2, that is used for the comparison
:return df_out: final dataframe
"""
df_1r = df_1[l_columns]
df_2r = df_2[l_columns].reset_index()
df_m = pd.merge(df_1r, df_2r, on=l_columns, how='inner')
row_indexes_m = df_m['index'].to_list()
row_indexes_df_2 = df_2.index.to_list()
row_indexes_out = [x for x in row_indexes_df_2 if x not in row_indexes_m]
df_out = df_2.loc[row_indexes_out]
return df_out
给出以下正确结果:
#row_indexes_out = [1,3]
df_output = df_drop_df(df_1, df_2, l_columns)
df_output
({'a': [2, 2],
'b': [1, 6],
'c': [3, 2],
'd': [4, 2],
'e': [1, 2]})
然而,对于实际应用,数据帧的大小具有以下尺寸,在我的本地计算机上大约需要 30 分钟来计算:
variable | shape |
---|---|
df1 | (3300,77) |
df2 | (642000,77) |
l_columns | list 12 |
df_out | (611000,77) |
(这意味着 df_1 中出现的每一行大约是 df_2 中的 10 次)
你能想出一个更快的方法来计算这个结果吗?
您可以尝试替换为以下几行:
row_indexes_df_2 = df_2.index.to_list()
row_indexes_out = [x for x in row_indexes_df_2 if x not in row_indexes_m]
df_out = df_2.loc[row_indexes_out]
波浪号运算符:
df_out = df_2.loc[~df_2.index.isin(row_indexes_m)]
应该会大大减少时间。