pandas 尝试透视大型 Dataframe ,但收到“IndexError:索引875914235超出大小为875909652'的轴0的范围

sd2nnvve  于 2023-03-21  发布在  其他
关注(0)|答案(1)|浏览(152)

我正在尝试透视此 Dataframe (“refine_dataset”):

就像这样:

movieUser_df = refined_dataset.pivot(
    index='userID',
     columns='primaryTitle',
      ## Replacing all movies users haven't rated with a rating of 0
      values='rating').fillna(0)

它返回错误:IndexError: index 875914235 is out of bounds for axis 0 with size 875909652
我已经用几乎相同的方法在过去的数据集(但小得多),我查找了为什么我可能会有这个问题,并在5年前遇到了this帖子,其中解释说这是一个正在进行的Pandas问题。除了对该帖子的几条评论,其中最近的一条是两年前的,我不知道是否有任何更新,我找不到其他人谈论这个问题或可能的解决方案。有人知道Pandas问题是否真的是我的问题吗?是否是,是否有任何方法我可以尝试和做不同的?

ecbunoof

ecbunoof1#

主要的问题是,如果你使用传统的pandas方法来创建一个包含太多行和列的pivot表,即使大多数值都使用了缺失row, column对的填充默认值(在你的例子中,所有用户没有评级的电影的评级为0),值的总数也会导致整数溢出,并且超过可用内存。
解决方案是使用sparse data structuresThis SO question有一个答案,它介绍了如何使用来自scipy.sparsecsr_matrix和来自pandas.api.typesCategoricalDtype来实现这一点,但它依赖于近年来从pandas中删除的pd.SparseDataFrame
下面的代码应该能够处理您的问题中的示例。

from scipy.sparse import csr_matrix
from pandas.api.types import CategoricalDtype

rcLabel, vLabel = ('userID', 'titleID'), 'rating'
rcCat = [CategoricalDtype(sorted(df[col].unique()), ordered=True) for col in rcLabel]
rc = [df[column].astype(aType).cat.codes for column, aType in zip(rcLabel, rcCat)]
mat = csr_matrix((df[vLabel], rc), shape=tuple(cat.categories.size for cat in rcCat))
dfOut = ( pd.DataFrame.sparse.from_spmatrix(
    mat, index=rcCat[0].categories, columns=rcCat[1].categories) )

生成示例输入的代码:

from random import randrange
dfLen = 3_500_000
titles = [f'tt{randrange(0,10_000_000):07}' for _ in range(dfLen)]
df = pd.DataFrame({
'titleID':titles,
'userID':[f'ur{randrange(0,67_000_000):08}' for _ in range(dfLen)],
'primaryTitle':titles,
'rating':[float(randrange(1,11)) for _ in range(dfLen)]})

以下是我所做的假设:

  • 输入 Dataframe 命名为df,旋转输出命名为dfOut
  • 有6700万独立用户
  • 有1000万个独特的标题
  • 有350万行(即userID, titleID对)

观察结果:

  • 在密集(非稀疏)枢轴中,这可以创建多达350万平方或约10万亿个值,而稀疏表示中约为350万个值。
  • 在我的示例中(从假设的人群中随机选择用户和标题),稀疏结果维度是[3410055行x 2952380列],info()方法报告memory usage: 195.1+ MB

相关问题