Pandas:如何管理大型CSV文件:将数据按组排序并保存到新文件中?

4

我有一个非常大的csv文件要处理,具体过程如下:

  • 按照3个列进行分组
  • 对于每个组,按照5个列对数据框进行排序
  • 将数据框写入csv文件

这是我的第一次尝试:

file = pd.read_csv('file.csv')
grouped = file.groupby([col1, col2, col3])
for key, df in grouped: 
    name = 'key.csv'
    df = df.sort_values(by=[col4, col5, col6, col7, col8])
    df.to_csv(name , index=False)
    yield name 

这种方法的优点是:每次迭代可以生成文件名,因此可以在等待其他文件准备好之前继续处理ETL过程,并且在写入CSV之前直接对数据帧进行排序。

缺点是:该文件太大,以至于无法像那样处理,会导致内存错误。

因此,我进行了第二次(也是当前的)尝试:

list_files = []
for chunk in pd.read_csv('file.csv', chunksize=CHUNKSIZE):
    grouped = chunk.groupby([col1, col2, col3])
    for key, df in grouped:
        name = 'key.csv'
        if Path(name).exists():
            df.to_csv(name, index=False, header=False, mode='a')
        else:
            list_files.append(name)
            df.to_csv(name, index=False)
yield list_files

这里使用chunk读取文件,不会出现内存问题。

但是,由于将数据附加到文件末尾(如果存在该文件),可以看到数据未排序。因此,需要生成所有文件的列表,并创建第二个函数来处理:

def sort(list_files):
    for filename in list_files:
        df = pd.read_csv(filename)
        df = df.sort_value(..)
        df.to_csv(filename)
        yield filename

所以我需要再次阅读每个文件,这里的过程需要在ETL过程的下一步之前创建所有的list_files。
关于这点,你知道是否有一种方法(目前我没有看到),可以解决内存错误的问题,并以更快的方式进行分组/排序处理吗? 也许(肯定)不可能,但任何改进都会有所帮助(将数据以比已排序数据更智能的方式附加到文件中,也许?)
谢谢
编辑:或许一种方法是在读取之前对大文件进行排序,但我仍然会遇到内存问题,不知道除了pandas是否有其他更好的方法可以做到呢?
2个回答

0

0

我曾经有过类似的经历,我建议你使用Dask,它为分析提供了先进的并行处理https://dask.org/,与Spark有些相似。然后你可以像第一次尝试时一样使用相同的代码。

  import dask.dataframe as dd

  file = dd.read_csv('file.csv')
  grouped = file.groupby([col1, col2, col3])
  for key, df in grouped: 
      name = 'key.csv'
      df = df.sort_values(by=[col4, col5, col6, col7, col8])
      df.to_csv(name , index=False)
      yield name 

提示:如果在将文件保存为 csv 时遇到内存错误,请在 to_csv 函数中使用 chunksize 选项


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接