Python:Unstacked DataFrame 太大,导致 int32 溢出
Posted
技术标签:
【中文标题】Python:Unstacked DataFrame 太大,导致 int32 溢出【英文标题】:Python: Unstacked DataFrame is too big, causing int32 overflow 【发布时间】:2020-08-28 14:46:15 【问题描述】:我有一个大数据集,当我尝试运行此代码时出现内存错误。
user_by_movie = user_items.groupby(['user_id', 'movie_id'])['rating'].max().unstack()
这是错误:
ValueError: Unstacked DataFrame is too big, causing int32 overflow
我已经在另一台机器上运行了它,它运行良好!我该如何解决这个错误?
【问题讨论】:
您尝试过使用 pivot 吗? 首先我使用了 pivot,我得到了这个错误。与枢轴相比,unstack 使用的内存更少。 分块读取数据是个好主意 【参考方案1】:根据谷歌的说法,你可以将你的 pandas 版本降级到 0.21,这对数据透视表和太大的数据没有问题。
【讨论】:
【参考方案2】:事实证明,这在 pandas 0.21 上不是问题。我正在使用 Jupyter 笔记本,其余代码需要最新版本的 pandas。所以我这样做了:
!pip install pandas==0.21
import pandas as pd
user_by_movie = user_items.groupby(['user_id', 'movie_id'])['rating'].max().unstack()
!pip install pandas
此代码适用于 Jupyter 笔记本。首先,它将 pandas 降级到 0.21 并运行代码。在获得所需的数据集后,它将 pandas 更新到最新版本。检查在 GitHub here 上提出的问题。 This 的帖子也有助于增加 Jupyter notebook 的内存。
【讨论】:
【参考方案3】:正如@Ehsan 指出的,我们可以分块旋转表格。
假设您有一个包含 3,355,205 行的 DataFrame! 让我们构建大小为 5000 的块:
chunk_size = 5000
chunks = [x for x in range(0, df.shape[0], chunk_size)]
for i in range(0, len(chunks) - 1):
print(chunks[i], chunks[i + 1] - 1)
0 4999
5000 9999
10000 14999
15000 19999
20000 24999
25000 29999
30000 34999
35000 39999
40000 44999
45000 49999
50000 54999
55000 59999
60000 64999
65000 69999
70000 74999
75000 79999
..continue..
您现在要做的就是在 pd.concat()
中进行列表理解:
df_new = pd.concat([df.iloc[ chunks[i]:chunks[i + 1] - 1 ].pivot(index='user_id', columns='item', values='views') for i in range(0, len(chunks) - 1)])
当您必须为某些推荐系统制作稀疏矩阵时,此答案很好。 之后你可以这样做:
from scipy import sparse
spr = sparse.coo_matrix(df_new.to_numpy())
【讨论】:
【参考方案4】:一些建议是降级到 pandas==0.21,这不是一个真正可行的解决方案!
我遇到了同样的问题,需要紧急修复意外的 int32 溢出。我们的推荐模型之一在生产中运行,并且在某个时候,用户群数量增加到超过 700 万条记录,大约 21k 项。
所以,为了解决我提到的@igorkf 对数据集进行分块的问题,使用 unstack 创建数据透视表并逐渐附加它。
import pandas as pd
from tqdm import tqdm
chunk_size = 50000
chunks = [x for x in range(0, df.shape[0], chunk_size)]
for i in range(0, len(chunks) - 1):
print(chunks[i], chunks[i + 1] - 1)
0 49999
50000 99999
100000 149999
150000 199999
200000 249990
.........................
pivot_df = pd.DataFrame()
for i in tqdm(range(0, len(chunks) - 1)):
chunk_df = df.iloc[ chunks[i]:chunks[i + 1] - 1]
interactions = (chunk_df.groupby([user_col, item_col])[rating_col]
.sum()
.unstack()
.reset_index()
.fillna(0)
.set_index(user_col)
)
print (interactions.shape)
pivot_df = pivot_df.append(interactions, sort=False)
然后我必须制作一个稀疏矩阵作为 lightFM 推荐模型的输入(运行矩阵分解算法)。您可以将它用于需要拆垛的任何用例。使用以下代码,转换为稀疏矩阵-
from scipy import sparse
import numpy as np
sparse_matrix = sparse.csr_matrix(df_new.to_numpy())
注意:Pandas 有 pivot_table 功能,如果您的数据很小,可以使用该功能进行拆垛。就我而言,pivot_table 真的很慢。
【讨论】:
以上是关于Python:Unstacked DataFrame 太大,导致 int32 溢出的主要内容,如果未能解决你的问题,请参考以下文章
大数据集,使用unstack()时收到“ Unstacked DataFrame太大,导致int32溢出”
大数据集,使用 unstack() 时收到“Unstacked DataFrame is too big,导致 int32 溢出”