Pandas DataFrame 可能有什么问题?

What could be wrong with a Pandas DataFrame?

我无法理解:我有一个函数可以从 S3 存储桶中读取一堆 csv 文件,将它们与 returns DataFrame 连接起来:

def create_df():
  df1 = pd.read_csv(s3_path + 'file_1.csv')
  df2 = pd.read_csv(s3_path + 'file_2.csv')

  return pd.concat([df1, df2], ignore_index=True)

我的第二个函数执行聚合:

def aggregate_values(df):
  columns = ['col_c', 'col_d']
  new_df = df.groupby(columns, as_index=False) \
    .agg({'col_a': 'sum', 'col_b': 'mean'})

  return new_df

函数 aggregate_values 由于内存不足错误而失败。

df = create_df()

# OOM error !!!
new_df = aggregate_values(df)

奇怪的是,如果我将 DataFrame 写入我的本地文件系统,然后将其读回,则聚合在新的 DataFrame 上正常工作。

df = create_df()
df.to_csv('path_to_store/f.csv', index=False)

df2 = pd.read_csv('path_to_store/f.csv')

# works fine!!!
new_df = aggregate_values(df2)

我的猜测是 create_df() 返回的 DataFrame 有问题。通过写出来并在 Pandas 中读回以某种方式解决了这个问题。但我想找出 DataFrame 到底出了什么问题。

我该如何调试这个问题?

已编辑

我机器上有32G内存运行代码。 DataFrame 有大约 200 万条记录,占用大约 0.5G 的存储和内存 space.

你没有评论你的内存大小, 也不是 .CSV 或数据框的大小。 但我可以冒险做出一些猜测。 我有几点观察:

  1. 连接后,您有机会核对 df1 和 df2。只需将 None 分配给它们,即可回收一些 RAM。
  2. .groupby() 可能接受密集的 numpy 数组并生成 higher-overhead 稀疏数组。你可能想调查一下。
  3. 计算平均值可能会变成例如int8 变成 float64,这显然会消耗更多 space。
  4. 这是最大的项目:.groupby() 可能返回了一个(可变的)视图而不是一个全新的 numpy 数组。文件系统的往返修复了这个问题,但是一个简单的 .copy() 会产生同样的效果,所以试试吧。

请post在这里回答,让我们知道进展如何。

我找到了问题,结果证明是个好问题。

create_df() 返回的 DataFrame 中的一列具有 dtype 类别。不确定这是怎么发生的,因为它本来就是字符串。该列在分组器中用于聚合。通过将 DataFrame 写入本地文件系统,然后将其读回,该列通过 Pandas 正确地得到 re-interpreted 作为字符串。

使用正确的数据类型,聚合运行 returns 很快,并且没有任何内存问题。我不明白为什么在分类列上分组会导致 OOM 错误——这是另一天的话题。