python-将数据帧酸洗到磁盘时出现内存错误

我有一个仅二进制(1或0)值的51K X 8.5K数据帧.

我写了以下代码:

酸洗数据到磁盘

outfile=open("df_preference.p", "wb")
pickle.dump(df_preference,outfile)
outfile.close()

它向我抛出内存错误,如下所示:

MemoryError                               Traceback (most recent call last)
 in ()
      2 
      3 outfile=open("df_preference.p", "wb")
----> 4 pickle.dump(df_preference,outfile)
      5 outfile.close()

我以为这意味着这些数据很大,无法腌制?但是它只有二进制值.

在此之前,我是从另一个具有正常计数和很多零的 dataframe 创建此数据集的.使用以下代码:

df_preference=df_recommender.applymap(lambda x: np.where(x >0, 1, 0))

这本身花费了一些时间来创建df_preference.矩阵大小相同.

我担心的是,如果花时间使用applymap创建 dataframe ,并且ii)由于内存错误甚至没有使 dataframe 腌制,那么我需要使用SVD和交替最小二乘法对df_prefence进行矩阵分解.那会更慢吗?如何解决这种慢速运行并解决内存错误?

谢谢

最佳答案

更新:

对于1和0值,可以使用int8(1字节)dtype,这将使内存使用量减少至少4倍.

(df_recommender > 0).astype(np.int8).to_pickle('/path/to/file.pickle')

这是一个具有51K x 9K数据帧的示例:

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

RangeIndex: 51000 entries, 0 to 50999
Columns: 9000 entries, 0 to 8999
dtypes: int32(9000)
memory usage: 1.7 GB

源DF需要1.7 GB的内存

In [6]: df_preference = (df>0).astype(int)

In [7]: df_preference.info()

RangeIndex: 51000 entries, 0 to 50999
Columns: 9000 entries, 0 to 8999
dtypes: int32(9000)
memory usage: 1.7 GB

导致DF再次需要1.7 GB内存

In [4]: df_preference = (df>0).astype(np.int8)

In [5]: df_preference.info()

RangeIndex: 51000 entries, 0 to 50999
Columns: 9000 entries, 0 to 8999
dtypes: int8(9000)
memory usage: 437.7 MB

使用int8 dtype只需438 MB

现在让我们将其另存为Pickle文件:

In [10]: df_preference.to_pickle('d:/temp/df_pref.pickle')

文件大小:

{ temp }  » ls -lh df_pref.pickle
-rw-r--r-- 1 Max None 438M May 28 09:20 df_pref.pickle

旧答案:

试试这个代替:

(df_recommender > 0).astype(int).to_pickle('/path/to/file.pickle')

说明:

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-有关详细信息,请参见this comparison