熊猫:将系列词典保存到磁盘

时间:2016-07-27 19:24:24

标签: python pandas dictionary scipy sparse-matrix

我有一个python pandas系列词典:

id           dicts
1            {'5': 1, '8': 20, '1800': 2}
2            {'2': 2, '8': 1, '1000': 25, '1651': 1}
...          ...
...          ...
...          ...
20000000     {'2': 1, '10': 20}

字典中的(键,值)表示('feature',count)。大约有2000个独特的功能。

该系列在熊猫中的内存使用量约为500MB。 将此对象写入磁盘的最佳方法是什么(具有理想的磁盘空间使用率,并且写入速度快,之后可以快速读回)?

考虑的选项(并尝试前两个):
- to_csv(但将字典视为字符串,因此之后转换回字典非常慢)
- cPickle(但执行期间内存不足)
- 转换为scipy稀疏矩阵结构

1 个答案:

答案 0 :(得分:3)

我很好奇你的Series只占用500MB。如果您使用.memory_usage方法,这将只返回每个python对象引用使用的总内存,这是您的Series正在存储的内容。这并不能解释词典的实际记忆。粗略计算20,000,000 * 288字节= 5.76GB应该是您的内存使用量。这288个字节是每个字典所需内存的保守估计。

转换为稀疏矩阵

无论如何,请尝试以下方法将数据转换为稀疏矩阵表示:

import numpy as np, pandas as pd
from sklearn.feature_extraction import DictVectorizer
from scipy.sparse import csr_matrix
import pickle

我会使用int而不是字符串作为键,因为这将在以后保持正确的顺序。因此,假设您的系列名为dict_series

dict_series = dict_series.apply(lambda d: {int(k):d[k] for k in d}

这可能是内存密集型的,您最好只使用Series作为键从dict创建int dv = DictVectorizer(dtype=np.int32) sparse = dv.fit_transform(dict_series) 。或者只是你可以跳过这一步。现在,构建稀疏矩阵:

sparse.data

保存到磁盘

现在,基本上,您的稀疏矩阵可以从3个字段重建:sparse.indicessparse.indptrsparse.shape,可选,sparse.data。保存数组sparse.indicessparse.indptrtofile的最快且最节省内存的方法是使用np.ndarray # to save sparse.data.tofile('data.dat') sparse.indices.tofile('indices.dat') sparse.indptr.tofile('indptr.dat') # don't forget your dict vectorizer! with open('dv.pickle', 'wb') as f: pickle.dump(dv,f) # pickle your dv to be able to recover your original data! 方法,该方法将数组保存为原始数据字节。来自documentation

  

这是一种便于快速存储阵列数据的功能。   关于字节序和精度的信息丢失了,所以这种方法不是   用于存档数据或传输数据的文件的不错选择   在具有不同字节序的机器之间。

因此,此方法会丢失任何dtype信息和endiamness。前一个问题可以通过简单地记录数据类型来处理,无论如何你将使用np.int32。如果您在本地工作,后一个问题不是问题,但如果可移植性很重要,您将需要研究存储信息的其他方法。

with open('dv.pickle', 'rb') as f:
    dv = pickle.load(f)

sparse = csr_matrix((np.fromfile('data.dat', dtype = np.int32),
                     np.fromfile('indices.dat', dtype = np.int32),
                     np.fromfile('indptr.dat', dtype = np.int32))

original = pd.Series(dv.inverse_transform(sparse))

要恢复所有内容:

Frog frogAsFrog = new Frog(7,"Freddy");
System.out.println(frogAsFrog);

Object frogAsObject = new Frog(5,"Rogers");
System.out.println(frogAsObject);
相关问题