5

我发现数据帧的稀疏版本在保存到磁盘时实际上比密集版本大得多。我究竟做错了什么?

test = pd.DataFrame(ones((4,4000)))
test.ix[:,:] = nan
test.ix[0,0] = 47

test.to_hdf('test3', 'df')
test.to_sparse(fill_value=nan).to_hdf('test4', 'df')

test.to_pickle('test5')
test.to_sparse(fill_value=nan).to_pickle('test6')

....
ls -sh test*
200K test3   16M test4  164K test5  516K test6

使用版本 0.12.0

我最终希望以大约 10% 的密度有效地存储 10^7 x 60 个数组,然后将它们拉入 Pandas 数据帧并使用它们。


编辑:感谢杰夫回答原始问题。后续问题:这似乎只能节省酸洗,而不是使用 HDF5 等其他格式。腌制是我最好的路线吗?

print shape(array_activity) #This is just 0s and 1s
(1020000, 60)

test = pd.DataFrame(array_activity)
test_sparse = test.to_sparse()
print test_sparse.density
0.0832333496732

test.to_hdf('1', 'df')
test_sparse.to_hdf('2', 'df')
test.to_pickle('3')
test_sparse.to_pickle('4')
!ls -sh 1 2 3 4
477M 1  544M 2  477M 3   83M 4

这些数据,作为 Matlab .mat 文件中的索引列表,小于 12M。我很想把它变成 HDF5/Pytables 格式,这样我就可以只获取特定的索引(其他文件更大,加载到内存中需要更长的时间),然后轻松地对它们执行 Pandasy 操作。也许我没有以正确的方式解决这个问题?

4

1 回答 1

6

您正在创建一个有 4000 列且只有 4 行的框架;sparse 按行处理,因此反转维度。

In [2]: from numpy import *

In [3]: test = pd.DataFrame(ones((4000,4)))

In [4]: test.ix[:,:] = nan

In [5]: test.ix[0,0] = 47

In [6]: test.to_hdf('test3', 'df')

In [7]: test.to_sparse(fill_value=nan).to_hdf('test4', 'df')

In [8]: test.to_pickle('test5')

In [9]: test.to_sparse(fill_value=nan).to_pickle('test6')

In [11]: !ls -sh test3 test4 test5 test6
164K test3  148K test4  160K test5   36K test6

跟进。您提供的商店是以table格式编写的,因此保存了密集版本(非常灵活且可查询的表格格式不支持稀疏,请参阅docs

此外,您可能希望尝试使用 2 种不同的稀疏格式表示来保存文件。

所以,这是一个示例会话:

df = 
In [1]: df = pd.read_hdf('store_compressed.h5','test')

In [2]: type(df)
Out[2]: pandas.core.frame.DataFrame

In [3]: df.to_sparse(kind='block').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [4]: df.to_sparse(kind='integer').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [5]: df.to_sparse(kind='block').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [6]: df.to_sparse(kind='integer').to_hdf('test_integer.h5','test',mode='w',complib='blosc',complevel=9)

In [7]: df.to_hdf('test_dense_fixed.h5','test',mode='w',complib='blosc',complevel=9)

In [8]: df.to_hdf('test_dense_table.h5','test',mode='w',format='table',complib='blosc',complevel=9)

In [9]: !ls -ltr *.h5
-rwxrwxr-x 1 jreback users 57015522 Feb  6 18:19 store_compressed.h5
-rw-rw-r-- 1 jreback users 30335044 Feb  6 19:01 test_block.h5
-rw-rw-r-- 1 jreback users 28547220 Feb  6 19:02 test_integer.h5
-rw-rw-r-- 1 jreback users 44540381 Feb  6 19:02 test_dense_fixed.h5
-rw-rw-r-- 1 jreback users 57744418 Feb  6 19:03 test_dense_table.h5

IIRC 他们是 0.12 中的一个错误,to_hdf它不会通过所有参数,所以你可能想使用:

with get_store('test.h5',mode='w',complib='blosc',complevel=9) as store:
    store.put('test',df)

这些基本上是作为一个集合存储的,SparseSeries因此如果密度低且不连续,那么就大小而言,它不会是最小的。尽管 YMMV,Pandas 稀疏套件可以更好地处理较少数量的连续块。scipy 也提供了一些稀疏处理工具。

尽管恕我直言,无论如何这些对于 HDF5 文件来说都是非常微不足道的大小,但您可以处理大量的行;并且文件大小可以轻松处理到 10 和 100 千兆字节(尽管推荐)。

此外,如果这确实是您可以查询的查找表,您可能会考虑使用表格式。

于 2014-02-06T18:29:58.473 回答