在笔记本中上传大 csv 文件以使用 python pandas 的最快方法是什么?

问题描述 投票:0回答:3

我正在尝试上传一个 250MB 的 csv 文件。基本上是400万行6列的时间序列数据(1分钟)。通常的程序是:

location = r'C:\Users\Name\Folder_1\Folder_2\file.csv'
df = pd.read_csv(location)

这个过程大约需要20分钟!!!.我非常初步地探索了以下选项

我想知道是否有人比较过这些选项(或更多)并且有一个明显的赢家。如果没有人回答,将来我会发布我的结果。我只是现在没有时间。

python csv pandas dataframe
3个回答
77
投票

以下是我对 DF 的读写比较结果(形状:4000000 x 6,内存大小 183.1 MB,未压缩的 CSV 大小 - 492 MB)。

以下存储格式比较:(

CSV
CSV.gzip
Pickle
HDF5
[各种压缩]):

                  read_s  write_s  size_ratio_to_CSV
storage
CSV               17.900    69.00              1.000
CSV.gzip          18.900   186.00              0.047
Pickle             0.173     1.77              0.374
HDF_fixed          0.196     2.03              0.435
HDF_tab            0.230     2.60              0.437
HDF_tab_zlib_c5    0.845     5.44              0.035
HDF_tab_zlib_c9    0.860     5.95              0.035
HDF_tab_bzip2_c5   2.500    36.50              0.011
HDF_tab_bzip2_c9   2.500    36.50              0.011

阅读

enter image description here

写入/保存

enter image description here

与未压缩的 CSV 文件的文件大小比率

enter image description here

原始数据:

CSV:

In [68]: %timeit df.to_csv(fcsv)
1 loop, best of 3: 1min 9s per loop

In [74]: %timeit pd.read_csv(fcsv)
1 loop, best of 3: 17.9 s per loop

CSV.gzip:

In [70]: %timeit df.to_csv(fcsv_gz, compression='gzip')
1 loop, best of 3: 3min 6s per loop

In [75]: %timeit pd.read_csv(fcsv_gz)
1 loop, best of 3: 18.9 s per loop

泡菜:

In [66]: %timeit df.to_pickle(fpckl)
1 loop, best of 3: 1.77 s per loop

In [72]: %timeit pd.read_pickle(fpckl)
10 loops, best of 3: 173 ms per loop

HDF (

format='fixed'
) [默认]:

In [67]: %timeit df.to_hdf(fh5, 'df')
1 loop, best of 3: 2.03 s per loop

In [73]: %timeit pd.read_hdf(fh5, 'df')
10 loops, best of 3: 196 ms per loop

HDF(

format='table'
):

In [37]: %timeit df.to_hdf('D:\\temp\\.data\\37010212_tab.h5', 'df', format='t')
1 loop, best of 3: 2.6 s per loop

In [38]: %timeit pd.read_hdf('D:\\temp\\.data\\37010212_tab.h5', 'df')
1 loop, best of 3: 230 ms per loop

HDF(

format='table', complib='zlib', complevel=5
):

In [40]: %timeit df.to_hdf('D:\\temp\\.data\\37010212_tab_compress_zlib5.h5', 'df', format='t', complevel=5, complib='zlib')
1 loop, best of 3: 5.44 s per loop

In [41]: %timeit pd.read_hdf('D:\\temp\\.data\\37010212_tab_compress_zlib5.h5', 'df')
1 loop, best of 3: 854 ms per loop

HDF(

format='table', complib='zlib', complevel=9
):

In [36]: %timeit df.to_hdf('D:\\temp\\.data\\37010212_tab_compress_zlib9.h5', 'df', format='t', complevel=9, complib='zlib')
1 loop, best of 3: 5.95 s per loop

In [39]: %timeit pd.read_hdf('D:\\temp\\.data\\37010212_tab_compress_zlib9.h5', 'df')
1 loop, best of 3: 860 ms per loop

HDF(

format='table', complib='bzip2', complevel=5
):

In [42]: %timeit df.to_hdf('D:\\temp\\.data\\37010212_tab_compress_bzip2_l5.h5', 'df', format='t', complevel=5, complib='bzip2')
1 loop, best of 3: 36.5 s per loop

In [43]: %timeit pd.read_hdf('D:\\temp\\.data\\37010212_tab_compress_bzip2_l5.h5', 'df')
1 loop, best of 3: 2.5 s per loop

HDF(

format='table', complib='bzip2', complevel=9
):

In [42]: %timeit df.to_hdf('D:\\temp\\.data\\37010212_tab_compress_bzip2_l9.h5', 'df', format='t', complevel=9, complib='bzip2')
1 loop, best of 3: 36.5 s per loop

In [43]: %timeit pd.read_hdf('D:\\temp\\.data\\37010212_tab_compress_bzip2_l9.h5', 'df')
1 loop, best of 3: 2.5 s per loop

PS 我无法在我的

Windows
笔记本上测试 feather

DF信息:

In [49]: df.shape
Out[49]: (4000000, 6)

In [50]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4000000 entries, 0 to 3999999
Data columns (total 6 columns):
a    datetime64[ns]
b    datetime64[ns]
c    datetime64[ns]
d    datetime64[ns]
e    datetime64[ns]
f    datetime64[ns]
dtypes: datetime64[ns](6)
memory usage: 183.1 MB

In [41]: df.head()
Out[41]:
                    a                   b                   c  \
0 1970-01-01 00:00:00 1970-01-01 00:01:00 1970-01-01 00:02:00
1 1970-01-01 00:01:00 1970-01-01 00:02:00 1970-01-01 00:03:00
2 1970-01-01 00:02:00 1970-01-01 00:03:00 1970-01-01 00:04:00
3 1970-01-01 00:03:00 1970-01-01 00:04:00 1970-01-01 00:05:00
4 1970-01-01 00:04:00 1970-01-01 00:05:00 1970-01-01 00:06:00

                    d                   e                   f
0 1970-01-01 00:03:00 1970-01-01 00:04:00 1970-01-01 00:05:00
1 1970-01-01 00:04:00 1970-01-01 00:05:00 1970-01-01 00:06:00
2 1970-01-01 00:05:00 1970-01-01 00:06:00 1970-01-01 00:07:00
3 1970-01-01 00:06:00 1970-01-01 00:07:00 1970-01-01 00:08:00
4 1970-01-01 00:07:00 1970-01-01 00:08:00 1970-01-01 00:09:00

文件大小:

{ .data }  » ls -lh 37010212.*                                                                          /d/temp/.data
-rw-r--r-- 1 Max None 492M May  3 22:21 37010212.csv
-rw-r--r-- 1 Max None  23M May  3 22:19 37010212.csv.gz
-rw-r--r-- 1 Max None 214M May  3 22:02 37010212.h5
-rw-r--r-- 1 Max None 184M May  3 22:02 37010212.pickle
-rw-r--r-- 1 Max None 215M May  4 10:39 37010212_tab.h5
-rw-r--r-- 1 Max None 5.4M May  4 10:46 37010212_tab_compress_bzip2_l5.h5
-rw-r--r-- 1 Max None 5.4M May  4 10:51 37010212_tab_compress_bzip2_l9.h5
-rw-r--r-- 1 Max None  17M May  4 10:42 37010212_tab_compress_zlib5.h5
-rw-r--r-- 1 Max None  17M May  4 10:36 37010212_tab_compress_zlib9.h5

结论:

Pickle
HDF5
要快得多,但是
HDF5
更方便 - 您可以在里面存储多个表/框架,您可以有条件地读取数据(查看
read_hdf()
中的where参数),您还可以压缩存储数据(
zlib
- 更快,
bzip2
- 提供更好的压缩比)等。

PS,如果你可以构建/使用

feather-format
- 与
HDF5
Pickle

相比,它应该更快

PPS: 不要将 Pickle 用于大数据帧,因为您可能最终会收到 SystemError: error return without exception set 错误消息。 这里这里也有描述。


1
投票

您可以使用 datatable 加载 csv 文件,然后将其转换为 pandas dataframe,它比使用 pandas read_csv() 加载要快得多

import datatable as dt

dt_df = dt.fread(csv_file)
pd_df = dt_df.to_pandas()

在 1 Go 的 csv 文件上,pandas read_csv 大约需要 34 分钟,而 datable fread 只需要 40 秒,这是一个巨大的差异(快 51 倍)。

您还可以仅使用数据表数据框,无需转换为 pandas 数据框(这取决于您想要的功能)。对数据表的有用介绍:https://www.kaggle.com/sudalairajkumar/getting-started-with-python-datatable


0
投票

如果您确实在寻找快速解决方案,我很惊讶没有人建议对数据进行分块并批量读取 - 最近没有处理过它,但在我之前的工作中,我必须使用〜处理一个文件30M 行非常频繁。我只需在调用 chunksize

 时使用 
read_csv
 参数并将其附加到形成主数据框。您还可以在 
iterator = True
参数列表中添加
read_csv

我阅读的时间从来不会超过 1 分钟。 (尽管它取决于块大小和系统配置)

df_csv = pd.read_csv('file', sep = '\t', iterator = True, chunksize = 1000) 
df = pd.concat(chunk for chunk in offer_csv])

此外,您还可以过滤掉每个块中的数据,这就是您下一步想要做的,使生活变得更轻松。

df = pd.concat(chunk[chunk['col'] > 100] for chunk in offer_csv])
© www.soinside.com 2019 - 2024. All rights reserved.