代码之家  ›  专栏  ›  技术社区  ›  OverflowingTheGlass

避免大熊猫数据帧上GroupBy的内存问题

  •  11
  • OverflowingTheGlass  · 技术社区  · 8 年前

    更新时间:

    熊猫df是这样创建的:

    df = pd.read_sql(query, engine)
    encoded = pd.get_dummies(df, columns=['account'])
    

    从该df创建dask df如下所示:

    df = dd.from_pandas(encoded, 50)
    

    使用dask执行操作不会导致任何可见的进展(使用dask诊断进行检查):

    result = df.groupby('journal_entry').max().reset_index().compute()
    

    原件:

    我有一个大熊猫df,有2.7M行和4000列。除四列外,所有列均为数据类型uint8。uint8列仅包含1或0的值。我正在尝试对df执行此操作:

    result = df.groupby('id').max().reset_index()
    

    可以预见,此操作会立即返回内存错误。我最初的想法是在水平和垂直方向上分块df。然而,这造成了一个混乱的局面,因为 .max() 需要跨所有uint8列执行,而不仅仅是一对列。此外,像这样对df进行分块仍然非常慢。我的机器上有32 GB的RAM。

    什么策略可以缓解内存问题?

    3 回复  |  直到 8 年前
        1
  •  33
  •   Heather Walker    6 年前

    如果数据中有任何分类列(而不是存储为对象列或字符串的类别),请确保在groupby命令中使用observed=True选项。这样可以确保只创建存在条目的行,例如,每个客户id、订单id组合只有一行,而不是创建n\u客户*n\u订单行!

    我刚刚在2600万行数据集上进行了groupby求和,从未超过7GB的RAM。在添加observed=True选项之前,它将达到62GB,然后耗尽。

        2
  •  8
  •   tobsecret    8 年前

    你可以使用 dask.dataframe 对于此任务

    import dask.dataframe as dd
    df = dd.from_pandas(df)
    result = df.groupby('id').max().reset_index().compute()
    

    您只需转换 pandas.DataFrame 变成一个 dask.dataframe .Dask是一个python核心外并行化框架,它提供了各种并行化容器类型,其中之一就是dataframe。它让你表演最普通的熊猫。数据帧操作与太大而无法放入内存的数据并行和/或分布。dask的核心是一组调度器和一个用于构建计算图的API,因此我们必须调用。compute(),以便实际进行任何计算。该库很容易安装,因为它大部分是用纯python编写的。

        3
  •  1
  •   klido    8 年前

    我想说的是,将数据按列进行拆分,比如说四次,然后使用每个子集的id来执行操作,然后重新合并