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

标签 pandas hdf5 pytables

我使用 pandas 和 hdf5 文件来处理大量数据(例如 10GB 或更多)。我想使用表格格式,以便在读取数据时能够有效地查询数据。但是,当我想将数据写入 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。当执行版本一时,使用表格格式,我的系统内存使用量突然上升到大约 8.5GB,这是我的 DataFrame 大小的两倍多。另一方面,对于具有固定格式的版本 2,没有额外的内存开销。

有谁知道问题出在哪里,或者我该如何防止这种巨大的内存开销?如果我有大约 10GB 的更大数据帧,我总是会因为这种开销而耗尽内存。 我知道在速度和其他方面,表格格式的性能并不是那么好,但我不明白为什么它应该使用这么多额外的内存(这足以容纳 2 个以上的数据帧完整副本) .

如果有人对此问题有解释和/或解决方案,那就太好了。

谢谢, 马库斯

最佳答案

<= 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  

关于写入 hdf 时的 Pandas/Pytable 内存开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29016093/

相关文章:

python - 如何用 pandas 中的字典替换 df 行中的重复项

python - 如何从单个列中获取多个列?

Python:从 DataFrame 中的两列创建结构化 numpy 结构化数组

python - HDF5 数据集数量限制

Python numpy MemoryError - 将多个 CSV 文件加载到 HDF5 存储中并读入 DataFrame

python - Pandas 中列名的异常排序

c++ - 打开 hdf5 字符串数据集

python - 是否可以在 PyTables 单元格中存储任意形状的多维数组?

python - 在同一 Python 进程中同时使用 h5py 和 pytables

python - 使用ptrepack回收hdf5文件中删除的节点