Pandas to_csv()保存大 Dataframe 速度慢

e5nqia27  于 2023-01-28  发布在  其他
关注(0)|答案(5)|浏览(448)

我猜这是一个简单的修复方法,但是我遇到了一个问题,用**to_csv()**函数将一个panda Dataframe 保存到csv文件要花将近一个小时,我使用的是anaconda python 2.7.12和panda(0.19.1)。

import os
import glob
import pandas as pd

src_files = glob.glob(os.path.join('/my/path', "*.csv.gz"))

# 1 - Takes 2 min to read 20m records from 30 files
for file_ in sorted(src_files):
    stage = pd.DataFrame()
    iter_csv = pd.read_csv(file_
                     , sep=','
                     , index_col=False
                     , header=0
                     , low_memory=False
                     , iterator=True
                     , chunksize=100000
                     , compression='gzip'
                     , memory_map=True
                     , encoding='utf-8')

    df = pd.concat([chunk for chunk in iter_csv])
    stage = stage.append(df, ignore_index=True)

# 2 - Takes 55 min to write 20m records from one dataframe
stage.to_csv('output.csv'
             , sep='|'
             , header=True
             , index=False
             , chunksize=100000
             , encoding='utf-8')

del stage

我已经确认了硬件和内存都在工作,但是这些是相当宽的表(~ 100列),大部分是数字(十进制)数据。
谢谢你,

j5fpnvbx

j5fpnvbx1#

添加我的小见解,因为'gzip'替代方法对我不起作用-尝试使用to_hdf方法。这大大减少了写入时间!(对于100 MB的文件不到一秒- CSV选项在30-55秒之间执行此操作)

stage.to_hdf(r'path/file.h5', key='stage', mode='w')
tcomlyy6

tcomlyy62#

您正在阅读压缩文件并写入纯文本文件。可能是IO瓶颈。
写入压缩文件可将写入速度提高10倍

stage.to_csv('output.csv.gz'
         , sep='|'
         , header=True
         , index=False
         , chunksize=100000
         , compression='gzip'
         , encoding='utf-8')

此外,您可以尝试不同的块大小和压缩方法(“bz2”、“xz”)。

hivapdat

hivapdat3#

你说“[...]的大部分数字(十进制)数据。"。你有任何列与时间和/或日期?
当一个8 GB的CSV只有数字/字符串值时,我在几秒钟内就保存了它,但是保存一个500 MB的CSV(包含两个Dates列)需要20分钟。因此,我建议在保存之前将每个日期列转换为字符串。下面的命令就足够了:

df['Column'] = df['Column'].astype(str)

我希望这个答案对你有所帮助。
我知道保存为.hdf文件解决了这个问题。但是,有时候,我们确实需要一个.csv文件。

4bbkushb

4bbkushb4#

尝试Apache的parquet文件格式或polars包,后者是常用pandas的替代方案。
我试着从我的服务器本地缓存一些数据,它有5900万行9列;pandas.DataFrame.to_csv完全停止,因此无法计时。
我在退出时放置了一个断点,并使用parquet将其保存下来,然后将其读回polars Dataframe (阅读没有计时,但大约需要5-10秒):

[ins] In [6]:import polars as pl
[ins] In []:pf = pl.read_parquet('path_to_my_data.parquet')

我使用polars将这个庞大的 Dataframe 写入csv:

[ins] In [8]: %timeit pf.write_csv('path_to_my_data.csv')                                                                         
24.3 s ± 5.79 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

我将polars Dataframe 转换为pandas Dataframe ,并使用hdfparquet将其记录下来:

[ins] In [9]: df = pf.to_pandas() 
[ins] In [11]: %timeit df.to_parquet('path_to_data2.parquet')                                                                                       
11.7 s ± 138 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[ins] In [12]: %timeit df.to_hdf('path_to_my_data.h5', key="stage", mode="w")  
15.4 s ± 723 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

parquet文件为1.8G,而h5文件为4.3G。来自pandasto_parquet已执行压缩(snappygzipbrotil),但我们作为最终用户不需要解压缩它。
如果您需要处理大量的数据,并且必须来回进行数据查询,那么这两种方法中的任何一种都是一种有前途的(如果不是超越的话)替代方法。

ego6inou

ego6inou5#

我曾经使用to_csv()输出到公司网络驱动器,速度太慢,需要一个小时才能输出1GB的csv文件。只是试图输出到我的笔记本电脑C:驱动器与to_csv()语句,它只花了2分钟输出1GB的csv文件。

相关问题