使用Pandas和/或Numpy进行读/写操作的最快文件格式

时间:2014-04-08 15:13:46

标签: python numpy pandas

我已经使用非常大的DataFrame工作了一段时间,我一直在使用csv格式来存储输入数据和结果。我注意到大量时间用于读取和写入这些文件,例如,这会大大减慢批处理数据的速度。我想知道文件格式本身是否相关。有没有 用于更快读/写Pandas DataFrames和/或Numpy数组的首选文件格式?

5 个答案:

答案 0 :(得分:17)

使用HDF5。节拍写平面文件。你可以查询。文档为here

这里是perf comparison vs SQL。更新为显示SQL / HDF_fixed / HDF_table / CSV写入和读取性能。

文档现在包含一个效果部分:

请参阅here

答案 1 :(得分:9)

为您的用例运行一些基准测试总是一个好主意。通过numpy存储原始结构我有很好的结果:

df.to_records().astype(mytype).tofile('mydata')
df = pd.DataFrame.from_records(np.fromfile('mydata', dtype=mytype))

它非常快,占用磁盘空间更少。但是:您需要跟踪dtype以重新加载数据,它不能在架构之间移植,并且它不支持HDF5的高级功能。 (numpy有一个more advanced binary format,旨在克服前两个限制,但我没有取得太大成功。)

更新:感谢您按下我的号码。我的基准测试表明HDF5确实赢了,至少在我的情况下。它的 更快更小的磁盘!这是我在数据帧中看到的大约280k行,7个浮点列和一个字符串索引:

In [15]: %timeit df.to_hdf('test_fixed.hdf', 'test', mode='w')
10 loops, best of 3: 172 ms per loop
In [17]: %timeit df.to_records().astype(mytype).tofile('raw_data')
1 loops, best of 3: 283 ms per loop
In [20]: %timeit pd.read_hdf('test_fixed.hdf', 'test')
10 loops, best of 3: 36.9 ms per loop
In [22]: %timeit pd.DataFrame.from_records(np.fromfile('raw_data', dtype=mytype))
10 loops, best of 3: 40.7 ms per loop
In [23]: ls -l raw_data test_fixed.hdf
-rw-r----- 1 altaurog altaurog 18167232 Apr  8 12:42 raw_data
-rw-r----- 1 altaurog altaurog 15537704 Apr  8 12:41 test_fixed.hdf

答案 2 :(得分:4)

HDF确实是一个非常好的选择,你也可以使用npy / npz一些警告:

这是一个基准,使用25k行和1000列填充随机浮点数据的数据框:

Saving to HDF took 0.49s
Saving to npy took 0.40s
Loading from HDF took 0.10s
Loading from npy took 0.061s
如果你不压缩数据,

npy的写入速​​度提高约20%,读取速度提高约40%。

用于生成上述输出的代码:

#!/usr/bin/python3

import pandas as pd
import random
import numpy as np
import time

start = time.time()
f = pd.DataFrame()
for i in range(1000):
  f['col_{}'.format(i)] = np.random.rand(25000)
print('Generating data took {}s'.format(time.time() - start))

start = time.time()
f.to_hdf('frame.hdf', 'main', format='fixed')
print('Saving to HDF took {}s'.format(time.time() - start))

start = time.time()
np.savez('frame.npz', f.index, f.values)
print('Saving to npy took {}s'.format(time.time() - start))

start = time.time()
pd.read_hdf('frame.hdf')
print('Loading from HDF took {}s'.format(time.time() - start))

start = time.time()
index, values = np.load('frame.npz')
pd.DataFrame(values, index=index)
print('Loading from npy took {}s'.format(time.time() - start))

答案 3 :(得分:3)

最近,熊猫使用pyarrow库(由韦斯·麦金尼本人和他平时的obsession for performance编写)添加了对实木复合地板格式的支持。

您只需要安装pyarrow库并使用方法read_parquetto_parquet。对于较大的数据集(几百兆字节或更多),Parquet的读写速度要快得多,并且它还可以跟踪dtype元数据,因此在从磁盘进行读写时,您不会丢失数据类型信息。实际上,它可以更有效地存储HDF5性能不佳的某些数据类型(例如字符串和时间戳:HDF5没有用于这些数据类型的本机数据类型,因此它使用pickle对其进行序列化,这对于大型数据集来说很慢)。 / p>

镶木地板也是一种柱状格式,这使得做两件事很容易:

  • 快速过滤掉您不感兴趣的列。使用CSV,您必须实际读取整个文件,然后,您才可以丢弃不需要的列。使用镶木地板,您实际上只能读取您感兴趣的列。

  • 使查询过滤出行并仅读取您关心的内容。

最近另一个有趣的发展是Feather文件格式,它也是由Wes Mckinney开发的。它本质上只是直接写入磁盘的未压缩arrow格式,因此它的写入速度可能比Parquet格式更快。缺点是文件要大2-3倍。

答案 4 :(得分:2)

如果优先考虑速度,我建议:

  • 羽毛-最快的
  • 镶木地板-速度较慢,但​​可以节省大量磁盘空间