【问题标题】:Pandas unstack() and pivot(): MemoryErrorPandas unstack() 和 pivot():MemoryError
【发布时间】:2021-01-11 17:57:45
【问题描述】:

问题描述

我想取消堆叠或旋转 DataFrame,但它引发了 numpy 异常 MemoryError: Unable to allocate 1.72 GiB for an array with shape (1844040704,) and data type bool。我已经尝试使用带有数字索引-> df.pivot() 和多索引-> df.unstack() ] 的DataFrame。两者都显示相同的异常,我不知道如何解决。我不觉得我有一个包含 175199 行的异常大的数据集。我之前在超过 5mio 行的 DataFrames 上使用了 unstack。 对于完整的分析,df 甚至会变大 2 倍!

我尝试使用 df_unstacked = df.unstack(level=0) 取消堆叠

附加信息

在pivot / unstack 之前,我必须使用df['row_num'] = np.arange(len(df)) 添加一个唯一索引,因为数据集包含(想要的)重复索引条目。那是由于夏令时,10 月的一天有 25 小时。第 2 个小时是重复的。

我在带有 python 3.7 的 virtualenv 中使用 Jupyterlab。

软件包版本:

  • 熊猫==1.1.2
  • numpy==1.19.2
  • jupyterlab==2.2.8

示例数据

                                    value
target_frame        row_num year         
2017-01-01 01:00:00 0       2016  10,3706
2017-01-01 01:15:00 1       2016  27,2456
2017-01-01 01:30:00 2       2016  20,4022
2017-01-01 01:45:00 3       2016  14,4911
2017-01-01 02:00:00 4       2016  14,2611
...                                   ...
2017-12-31 23:45:00 175195  2020  30,7177
2017-01-01 00:00:00 175196  2020  21,4708
2017-01-01 00:15:00 175197  2020  44,9192
2017-01-01 00:30:00 175198  2020  37,8560
2017-01-01 00:45:00 175199  2020  30,9901

[175200 rows x 1 columns]

想要的结果

索引将包含重复项。作为记录,我不在乎它是索引还是常规列。

                     value
year                 2016     2017  ...  2020
target_frame                  
2017-01-01 01:00:00  10,3706  11    ...  32
2017-01-01 01:15:00  27,2456  12    ...  32
2017-01-01 01:30:00  20,4022  13    ...  541
2017-01-01 01:45:00  14,4911  51    ...  123
2017-01-01 02:00:00  14,2611  56    ...  12
...                                   ...
2017-12-31 23:45:00  30,7177  12    ...  12
2017-01-01 00:00:00  21,4708  21    ...  12
2017-01-01 00:15:00  44,9192  21    ...  13
2017-01-01 00:30:00  37,8560  21    ...  11
2017-01-01 00:45:00  30,9901  12    ...  10

[35040 rows x 5 columns]

【问题讨论】:

    标签: python python-3.x pandas out-of-memory


    【解决方案1】:

    我将尝试通过解决内存不足的问题以及解决方法来帮助您。

    由于您的数据已经有近 20 亿条记录,并且错误与内存有关,因此我将重点关注这一点,而不考虑转换本身。

    如果您使用的是 df、df_pivoted、df_unstacked 等。每次转换都会创建一个新变量,并增加内存消耗。所以在这个过程中清除内存很重要。即使您的数据似乎不足以消耗所有内存。

    解决此问题的一种方法是处理“块”并将每个转换步骤保存到文件中以清除内存。

    所以第一步是保存文件,用一个简单的'dataframe.to_csv()'。

    第二步是使用适合内存的部分数据进行转换。

    为此,pandas.read_csv () 函数中有一个参数,称为“chuncksize”,可将您的导入对象转换为迭代 TextFileReader。

    这样,如果你想访问数据信息,你需要遍历它。

    iterator = pandas.read_csv('file.csv', chuncksize=32)
    iterator.shape # will raise an error.
    
    AttributeError: 'TextFileReader' object has no attribute 'shape'
    

    正确的做法:

    for chunck in iterator:
        print (chunck.shape)
    

    输出:

    (32, ncols)
    

    这样,为了解决您的问题,您可以使用块并使用连接函数在您需要数据时进行分析。

    【讨论】:

    • 您好,感谢您的努力。我遗漏了一些东西,为什么我的数据有 20 亿条记录?我有 175.200 行。也许这就是问题的一部分?如果我将我的 df 保存到泡菜中,它大约有 5 MB 编辑:好的,我明白你的意思了。 numpy 错误包含 20 亿条记录。但为什么会这样呢?
    • 对!我认为它是 175000 行多列,示例中只有一个示例。但是如果数据真的很小,那么问​​题一定出在应用重塑的函数中,它们的行为与您预期的不同,并且正在以一种爆炸式内存消耗的方式格式化数据。试着回顾一下你是如何使用这些功能的,如果参数调整得很好,并且还可以可视化中间步骤。如果一切正常,请尝试使用少量数据进行操作,这样即使有错误,您也可以看到发生了什么并了解问题所在。
    【解决方案2】:

    我认为这可能是 pandas 或 numpy 中的错误。有不同的错误消息,带有不同的 pandas 和 numpy 版本(Anaconda 与 pip)。我自己编写了转换代码,它很快就运行了。

    # Get the 2017 timestamp for the side_df
    side_df = pd.DataFrame ({'timestamp': next_df.loc[next_df['year'] == 2017]['target_frame']})
    
    for year in next_df['year'].unique():
        
        side_df[year] = next_df.loc[next_df['year'] == year]['value']
    
    display(side_df)
    

    结果:

                    timestamp     2016     2017     2018     2019     2020
    8839  2017-01-01 01:00:00  10,3706   4,4184  14,7919  30,6942  31,0594
    8840  2017-01-01 01:15:00  27,2456  23,7641  31,0019  40,2778  46,8350
    8841  2017-01-01 01:30:00  20,4022  14,9732  23,8531  34,4941  41,3688
    8842  2017-01-01 01:45:00  14,4911   9,4986  17,0181  28,8678  37,8213
    8843  2017-01-01 02:00:00  14,2611   5,1241  14,0869  24,3203  34,4150
    ...                   ...      ...      ...      ...      ...      ...
    43874 2017-12-31 23:45:00  10,9256  15,2959  22,6000  40,1677      NaN
    43875 2017-01-01 00:00:00  10,9706   4,8184  11,5150  30,9208      NaN
    43876 2017-01-01 00:15:00  35,6275  25,8251  30,2893  41,5722      NaN
    43877 2017-01-01 00:30:00   24,555  17,7821  24,2928  35,5510      NaN
    43878 2017-01-01 00:45:00     5,61  11,7059  20,0477  31,2884      NaN
    

    数据集中还有一些问题(比如 NaN),但这与这个问题无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 2019-02-13
      • 2019-04-22
      • 2017-06-28
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多