Memory Error while pickling a data frame to disk
我有一个51K X 8.5K数据帧,只有二进制(1或0)值。
我写了以下代码:
将数据腌制到磁盘上
1 2 3 | outfile=open("df_preference.p","wb") pickle.dump(df_preference,outfile) outfile.close() |
它抛出了我的内存错误如下:
1 2 3 4 5 6 | MemoryError Traceback (most recent call last) <ipython-input-48-de66e880aacb> in <module>() 2 3 outfile=open("df_preference.p","wb") ----> 4 pickle.dump(df_preference,outfile) 5 outfile.close() |
我假设它意味着这个数据很大而且不能被腌制? 但它只有二进制值。
在此之前,我从另一个具有正常计数和大量零的数据框架创建了此数据集。 使用以下代码:
1 | df_preference=df_recommender.applymap(lambda x: np.where(x >0, 1, 0)) |
这本身需要一些时间来创建df_preference。 相同尺寸的矩阵。
我担心的是,如果使用applymap创建数据框需要时间,而ii)由于内存错误甚至没有腌制数据帧,那么我需要使用SVD和交替最小二乘法对此df_prefence进行矩阵分解。 那会更慢吗? 如何解决这个慢速运行并解决内存错误?
谢谢
更新:
对于
1 | (df_recommender > 0).astype(np.int8).to_pickle('/path/to/file.pickle') |
以下是51K x 9K数据帧的示例:
1 2 3 4 5 6 7 8 9 10 11 | In [1]: df = pd.DataFrame(np.random.randint(0, 10, size=(51000, 9000))) In [2]: df.shape Out[2]: (51000, 9000) In [3]: df.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 51000 entries, 0 to 50999 Columns: 9000 entries, 0 to 8999 dtypes: int32(9000) memory usage: 1.7 GB |
源DF需要1.7 GB的内存
1 2 3 4 5 6 7 8 | In [6]: df_preference = (df>0).astype(int) In [7]: df_preference.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 51000 entries, 0 to 50999 Columns: 9000 entries, 0 to 8999 dtypes: int32(9000) memory usage: 1.7 GB |
结果DF再次需要1.7 GB的内存
1 2 3 4 5 6 7 8 | In [4]: df_preference = (df>0).astype(np.int8) In [5]: df_preference.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 51000 entries, 0 to 50999 Columns: 9000 entries, 0 to 8999 dtypes: int8(9000) memory usage: 437.7 MB |
使用
现在让我们将它保存为Pickle文件:
1 | In [10]: df_preference.to_pickle('d:/temp/df_pref.pickle') |
文件大小:
1 2 | { temp } ? ls -lh df_pref.pickle -rw-r--r-- 1 Max None 438M May 28 09:20 df_pref.pickle |
老答案:
试试这个:
1 | (df_recommender > 0).astype(int).to_pickle('/path/to/file.pickle') |
Explanataion:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | In [200]: df Out[200]: a b c 0 4 3 3 1 1 2 1 2 2 1 0 3 2 0 1 4 2 0 4 In [201]: (df>0).astype(int) Out[201]: a b c 0 1 1 1 1 1 1 1 2 1 1 0 3 1 0 1 4 1 0 1 |
PS你可能还想将你的DF保存为HDF5文件而不是Pickle - 请参阅此比较以获取详细信息