Pandas/Pytable 写入 hdf 时的内存开销

Pandas/Pytable memory overhead when writing to hdf

我使用 pandas 和 hdf5 文件来处理大量数据(例如 10GB 或更多)。我想使用 table 格式,以便在读取数据时能够有效地查询数据。但是,当我想将数据写入 hdf 存储时(使用 DataFrame.to_hdf()),它会产生巨大的内存开销。考虑以下示例:

import pandas as pd
import numpy as np
from random import sample

nrows   = 1000000
ncols   = 500

# create a big dataframe
df = pd.DataFrame(np.random.rand(nrows,ncols)) 

# 1) Desired table format: uses huge memory overhead
df.to_hdf('test.hdf', 'random', format='table') # use lots of additional memory

# 2) Fixed format,  uses no additional memory
df.to_hdf('test2.hdf', 'random') 

当我执行 df.info() 时,我看到存储空间大小为 3.7GB。当执行版本一时,使用 table 格式,我的系统内存使用量突然上升到大约 8.5GB,这是我的 DataFrame 大小的两倍多。另一方面,对于具有固定格式的第二版,没有额外的内存开销。

有谁知道问题出在哪里,或者我该如何防止这种巨大的内存开销?如果我有大约 10GB 的更大数据帧,由于这种开销,我总是 运行 内存不足。 我知道在速度和其他方面 table 格式的性能并不是那么好,但我不明白为什么它应该使用这么多额外的内存(这足够超过 2 个完整副本数据框)。

如果有人能解释一下and/or这个问题的解决方案就好了。

谢谢, 马库斯

在 <= 0.15.2

In [1]: df = pd.DataFrame(np.random.rand(1000000,500))
df.info()

In [2]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Columns: 500 entries, 0 to 499
dtypes: float64(500)
memory usage: 3.7 GB
In [3]: %memit -r 1 df.to_hdf('test.h5','df',format='table',mode='w')
peak memory: 11029.49 MiB, increment: 7130.57 MiB

<= 0.15.2 中效率低下,最终复制数据 1-2 次。您可以在 0.16.0 之前将此作为解决方法(已修复)

In [9]: %cpaste
def f(df):
  g = df.groupby(np.arange(len(df))/10000)
  store = pd.HDFStore('test.h5',mode='w')
  for _, grp in g:
    store.append('df',grp, index=False)
  store.get_storer('df').create_index()

In [11]: %memit -r 1 f(df)
peak memory: 7977.26 MiB, increment: 4079.32 MiB

0.16.0(2015 年 3 月第 3 周),在 this PR

之后
In [2]: %memit -r 1 df.to_hdf('test.h5','df',format='table',mode='w')
peak memory: 4669.21 MiB, increment: 794.57 MiB