Python 中 groupby 函数的奇怪行为(内存不足)

问题描述 投票:0回答:1

我有一个很长的代码,在某些时候有一个非常小的数据框,有 813 行和 16 列。 对于这个数据框,我应用了 groupby 函数

fm = fm.groupby(['Tower_ID'                 ,'Cell_ID'                 ,'Alarm ID'                 ,'Severity'                 ,'Alarm Type'                 ,'Alarm Text'                 ,'Supplementary Info'                 ,'PERIOD_START_TIME'                 #,'File_Name'                ]
               ).agg({'Full_Start_Date': 'min'
                      ,'Full_End_Date': 'max'
                      ,'Alarm hold time (sec)': 'sum'
                      ,'End_Date': 'max'
                      ,'Cross_Over': 'max'
                      ,'Cross_Over_diff': 'max'
                     }
                    )

这会导致内存不足的错误 numpy.core._exceptions._ArrayMemoryError:无法为形状为(1485993600)和数据类型为int64的数组分配11.1 GiB

我尝试过的事情。 1 - 我使用不同的变量,例如bananas = fm.groupby .....而不是fm = fm .....相同的结果 2 - 尝试将列的格式更改为我需要的确切类型,类别,int等......相同的结果

什么有效

在 groupby 之前,我将 fm 数据帧保存到文件中,然后将文件读回 fm

fm.to_excel('C:\\home\\fm_data.xlsx')
fm = pd.read_excel('C:\\home\\fm_data.xlsx')

这有效!

任何人都可以知道为什么吗? 这是一个非常非常糟糕的解决方案,我想了解可能出现的问题。 我很感激您的帮助。

python pandas group-by out-of-memory
1个回答
0
投票

如果您想为每个唯一的 ID

.agg
,那么您使用的
.groupby
有一个重大问题。它将运行八 (8) 个唯一 ID 的所有可能组合,即 256 个唯一组合。如果您想要
.agg
代表每个独立的 id,这里是您可以使用的代码:

# Columns to group by
group_columns = [
   'Tower_ID', 'Cell_ID', 'Alarm ID', 'Severity', 'Alarm Type', 
   'Alarm Text', 'Supplementary Info', 'PERIOD_START_TIME'
]

# Aggregation columns to dictionary
agg_dict = {
    'Full_Start_Date': 'min',
    'Full_End_Date': 'max',
    'Alarm hold time (sec)': 'sum',
    'End_Date': 'max',
    'Cross_Over': 'max',
    'Cross_Over_diff': 'max'
}

# performs groupby and aggregation for each ID column separately
grouped_dfs = {}
for col in group_columns:
   grouped_dfs[col] = fm.groupby(col).agg(agg_dict).reset_index()

如果您确实想运行 8 个唯一 id 的所有可能组合,则运行过程非常昂贵,并且通常会出现

out of memory
错误。 让我们在这里分解一下数学:

  • 如果每个
    groupby
    列只有 1 个唯一元素,则会有
    2^{8} = 256
    唯一组合。
  • 考虑到 813 行,我猜每列中平均至少有 20 个唯一元素。这是:
    2^{20*8} = 1,4615e48
    。 1 有 48 个零,计算起来确实是一个很大的数字。
© www.soinside.com 2019 - 2024. All rights reserved.