簡體   English   中英

熊貓:將系列詞典保存到磁盤

[英]Pandas : saving Series of dictionaries to disk

我有一個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。 將此對象寫入磁盤的最佳方法是什么(理想情況下磁盤空間使用率低,寫入速度快,后續快速讀回)?

考慮的選項(並在前2個嘗試過):
- to_csv(但將字典視為字符串,因此之后轉換回字典非常慢)
- cPickle(但執行期間內存不足)
- 轉換為scipy稀疏矩陣結構

我很好奇你的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}

這可能是內存密集型的,你可能最好只使用int s作為鍵從一開始創建你的dict Series 或者只是你可以跳過這一步。 現在,構建稀疏矩陣:

dv = DictVectorizer(dtype=np.int32)
sparse = dv.fit_transform(dict_series)

保存到磁盤

現在,基本上,您的稀疏矩陣可以從3個字段重建: sparse.datasparse.indicessparse.indptr ,可選的sparse.shape 保存數據sparse.datasparse.indicessparse.indptr的最快且最節省內存的方法是使用np.ndarray tofile方法,該方法將數組保存為原始字節。 文檔

這是一種便於快速存儲陣列數據的功能。 有關字節序和精度的信息會丟失,因此對於要在具有不同字節序的計算機之間存檔數據或傳輸數據的文件,此方法不是一個好的選擇。

所以這種方法會丟失任何dtype信息和endiamness。 前一個問題可以通過簡單地記錄數據類型來處理,無論如何你將使用np.int32。 如果您在本地工作,后一個問題不是問題,但如果可移植性很重要,您將需要研究存儲信息的其他方法。

# 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!

要恢復一切:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM