【问题标题】:How to efficiently find the inverse intersection between two large dataframes with pandas?如何有效地找到两个大数据框与熊猫之间的逆交点?
【发布时间】:2021-07-04 07:28:36
【问题描述】:

我试图找到两个 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 倍)

你能想出一种更快的方法来计算这个结果吗?

【问题讨论】:

  • 您是否正在寻找这两个数据框的交集相对于公共列的补集?
  • 是的,相交的补码比我所说的(逆相交)更正确。需要这么长时间的应该是合并步骤而不是问题的反转,对吗?它不仅是所有常见的列,而且是特定的列(两个数据框需要共有)。
  • 您是否完全确定您所得到的实际上是您用作键的列的交集的补充?我得到一个额外的行,我只使用补码的定义。
  • 你能发布你在做什么吗?结果应该是第 1 行和第 3 行,因为在 a、b 和 e 列上比较了两个数据框

标签: python pandas dataframe bigdata intersection


【解决方案1】:

您可以尝试替换以下行:

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)]

应该会大大减少时间。

【讨论】:

  • 这个步骤现在在我的本地机器上只需要 0.5 秒。
猜你喜欢
  • 2021-10-06
  • 2018-07-14
  • 2021-12-16
  • 1970-01-01
  • 2015-02-10
  • 2022-08-22
  • 2019-02-26
  • 2018-04-18
  • 1970-01-01
相关资源
最近更新 更多