与 HDF5 相比,为什么 pandas 和 dask 在从 CSV 导入时表现更好?
Why do pandas and dask perform better when importing from CSV compared to HDF5?
我正在使用一个当前运行大型 (>5GB) .csv 文件的系统。为了提高性能,我正在测试 (A) 从磁盘创建数据帧的不同方法(pandas VS dask) as well as (B) different ways to store results to disk (.csv VS hdf5 文件)。
为了对性能进行基准测试,我做了以下操作:
def dask_read_from_hdf():
results_dd_hdf = dd.read_hdf('store.h5', key='period1', columns = ['Security'])
analyzed_stocks_dd_hdf = results_dd_hdf.Security.unique()
hdf.close()
def pandas_read_from_hdf():
results_pd_hdf = pd.read_hdf('store.h5', key='period1', columns = ['Security'])
analyzed_stocks_pd_hdf = results_pd_hdf.Security.unique()
hdf.close()
def dask_read_from_csv():
results_dd_csv = dd.read_csv(results_path, sep = ",", usecols = [0], header = 1, names = ["Security"])
analyzed_stocks_dd_csv = results_dd_csv.Security.unique()
def pandas_read_from_csv():
results_pd_csv = pd.read_csv(results_path, sep = ",", usecols = [0], header = 1, names = ["Security"])
analyzed_stocks_pd_csv = results_pd_csv.Security.unique()
print "dask hdf performance"
%timeit dask_read_from_hdf()
gc.collect()
print""
print "pandas hdf performance"
%timeit pandas_read_from_hdf()
gc.collect()
print""
print "dask csv performance"
%timeit dask_read_from_csv()
gc.collect()
print""
print "pandas csv performance"
%timeit pandas_read_from_csv()
gc.collect()
我的发现是:
dask hdf performance
10 loops, best of 3: 133 ms per loop
pandas hdf performance
1 loop, best of 3: 1.42 s per loop
dask csv performance
1 loop, best of 3: 7.88 ms per loop
pandas csv performance
1 loop, best of 3: 827 ms per loop
当 hdf5 存储的访问速度比 .csv 快,并且 dask 创建数据帧的速度比 pandas 快时,为什么来自 hdf5 的 dask 比来自 csv 的 dask 慢?我做错了什么吗?
什么时候从 HDF5 存储对象创建 dask 数据帧对性能有意义?
HDF5 在处理数字数据时效率最高,我猜您正在读取单个字符串列,这是它的弱点。
使用 Categorical
存储字符串可以显着提高 HDF5 字符串数据的性能,假设基数相对较低(重复值的数量较多)
这是不久前的事了,但是这里有一个很好的博客 post 正是考虑这些因素。
http://matthewrocklin.com/blog/work/2015/03/16/Fast-Serialization
您也可以考虑使用 parquet - 它与 HDF5 的相似之处在于它是一种二进制格式,但它是面向列的,因此像这样的单列选择可能会更快。
最近 (2016-2017) 在实现 parquet->pandas 的快速原生 reader 和 pandas 的下一个主要版本(0.21
) 将内置 to_parquet
和 pd.read_parquet
函数。
https://arrow.apache.org/docs/python/parquet.html
https://fastparquet.readthedocs.io/en/latest/
https://matthewrocklin.com/blog//work/2017/06/28/use-parquet
我正在使用一个当前运行大型 (>5GB) .csv 文件的系统。为了提高性能,我正在测试 (A) 从磁盘创建数据帧的不同方法(pandas VS dask) as well as (B) different ways to store results to disk (.csv VS hdf5 文件)。
为了对性能进行基准测试,我做了以下操作:
def dask_read_from_hdf():
results_dd_hdf = dd.read_hdf('store.h5', key='period1', columns = ['Security'])
analyzed_stocks_dd_hdf = results_dd_hdf.Security.unique()
hdf.close()
def pandas_read_from_hdf():
results_pd_hdf = pd.read_hdf('store.h5', key='period1', columns = ['Security'])
analyzed_stocks_pd_hdf = results_pd_hdf.Security.unique()
hdf.close()
def dask_read_from_csv():
results_dd_csv = dd.read_csv(results_path, sep = ",", usecols = [0], header = 1, names = ["Security"])
analyzed_stocks_dd_csv = results_dd_csv.Security.unique()
def pandas_read_from_csv():
results_pd_csv = pd.read_csv(results_path, sep = ",", usecols = [0], header = 1, names = ["Security"])
analyzed_stocks_pd_csv = results_pd_csv.Security.unique()
print "dask hdf performance"
%timeit dask_read_from_hdf()
gc.collect()
print""
print "pandas hdf performance"
%timeit pandas_read_from_hdf()
gc.collect()
print""
print "dask csv performance"
%timeit dask_read_from_csv()
gc.collect()
print""
print "pandas csv performance"
%timeit pandas_read_from_csv()
gc.collect()
我的发现是:
dask hdf performance
10 loops, best of 3: 133 ms per loop
pandas hdf performance
1 loop, best of 3: 1.42 s per loop
dask csv performance
1 loop, best of 3: 7.88 ms per loop
pandas csv performance
1 loop, best of 3: 827 ms per loop
当 hdf5 存储的访问速度比 .csv 快,并且 dask 创建数据帧的速度比 pandas 快时,为什么来自 hdf5 的 dask 比来自 csv 的 dask 慢?我做错了什么吗?
什么时候从 HDF5 存储对象创建 dask 数据帧对性能有意义?
HDF5 在处理数字数据时效率最高,我猜您正在读取单个字符串列,这是它的弱点。
使用 Categorical
存储字符串可以显着提高 HDF5 字符串数据的性能,假设基数相对较低(重复值的数量较多)
这是不久前的事了,但是这里有一个很好的博客 post 正是考虑这些因素。 http://matthewrocklin.com/blog/work/2015/03/16/Fast-Serialization
您也可以考虑使用 parquet - 它与 HDF5 的相似之处在于它是一种二进制格式,但它是面向列的,因此像这样的单列选择可能会更快。
最近 (2016-2017) 在实现 parquet->pandas 的快速原生 reader 和 pandas 的下一个主要版本(0.21
) 将内置 to_parquet
和 pd.read_parquet
函数。
https://arrow.apache.org/docs/python/parquet.html
https://fastparquet.readthedocs.io/en/latest/
https://matthewrocklin.com/blog//work/2017/06/28/use-parquet