【问题标题】:Python: Unstacked DataFrame is too big, causing int32 overflowPython:Unstacked DataFrame 太大,导致 int32 溢出
【发布时间】: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 使用的内存更少。
  • 分块读取数据是个好主意

标签: python pandas data-science data-analysis


【解决方案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 真的很慢。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-12
          • 2022-06-28
          • 1970-01-01
          • 1970-01-01
          • 2015-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多