numpy处理多个大数组时出现内存错误

1 投票
2 回答
527 浏览
提问于 2025-04-18 15:38

我正在尝试对一系列大数组进行一些计算,但我总是遇到错误:

MemoryError

总共有9个 grain_size 数组,大小是 2745 行乘 2654 列(注意:这里其实可以用一个单一的浮点数代替数组,因为每个单元格里的数都是一样的,并且这个数不会改变),还有9个 g_pro 数组,大小也是 2745 行乘 2654,以及我下面创建的9个数组。

所以我想问的是,有没有办法解决这个问题呢?

# Create empty arrays to store the information
Fs1 = np.zeros_like(g_pro_1, dtype = float)
Fs2 = np.zeros_like(g_pro_1, dtype = float)
Fs3 = np.zeros_like(g_pro_1, dtype = float)
Fs4 = np.zeros_like(g_pro_1, dtype = float)
Fs5 = np.zeros_like(g_pro_1, dtype = float)
Fs6 = np.zeros_like(g_pro_1, dtype = float)
Fs7 = np.zeros_like(g_pro_1, dtype = float)
Fs8 = np.zeros_like(g_pro_1, dtype = float)
Fs9 = np.zeros_like(g_pro_1, dtype = float)

# Check where the condition is true
np.putmask(Fs1, np.logical_and(grain_size_1_array > 0.0000625, grain_size_1_array <= 0.002), g_pro_1)
np.putmask(Fs2, np.logical_and(grain_size_2_array > 0.0000625, grain_size_2_array <= 0.002), g_pro_2)
np.putmask(Fs3, np.logical_and(grain_size_3_array > 0.0000625, grain_size_3_array <= 0.002), g_pro_3)
np.putmask(Fs4, np.logical_and(grain_size_4_array > 0.0000625, grain_size_4_array <= 0.002), g_pro_4)
np.putmask(Fs5, np.logical_and(grain_size_5_array > 0.0000625, grain_size_5_array <= 0.002), g_pro_5)
np.putmask(Fs6, np.logical_and(grain_size_6_array > 0.0000625, grain_size_6_array <= 0.002), g_pro_6)
np.putmask(Fs7, np.logical_and(grain_size_7_array > 0.0000625, grain_size_7_array <= 0.002), g_pro_7)
np.putmask(Fs8, np.logical_and(grain_size_8_array > 0.0000625, grain_size_8_array <= 0.002), g_pro_8)
np.putmask(Fs9, np.logical_and(grain_size_9_array > 0.0000625, grain_size_9_array <= 0.002), g_pro_9)

Fs = Fs1 + Fs2 + Fs3 + Fs4 + Fs5 + Fs6 + Fs7 + Fs8 + Fs9
Fs[self.discharge == -9999] = -9999

现在对我有效的代码是:

Fs = np.zeros_like(g_pro_1, dtype = float)

    grain_array_list = [self.grain_size_1, self.grain_size_2, self.grain_size_3,    self.grain_size_4, self.grain_size_5, self.grain_size_6, self.grain_size_7, self.grain_size_8, self.grain_size_9]
    proportions_list = [g_pro_1, g_pro_2, g_pro_3, g_pro_4, g_pro_5, g_pro_6, g_pro_7, g_pro_8, g_pro_9]

    for proportion, grain in izip(proportions_list, grain_array_list):  
        if grain > 0.0000625 and grain <= 0.002:
            print grain
            Fs = Fs + proportion

    Fs[self.discharge == -9999] = -9999

2 个回答

1

你的例子需要 9*2745*2654*sizeof(float) 字节,也就是大约 500 兆字节,来存储 grain_size 数组,另外还需要同样多的空间来存储 g_pro 数组。为了运行 logical_and 函数,比较结果的参数数组也需要存储,这又要增加大约 100 兆字节。也许你真的就是内存不够用了?

你可以尝试:

  • 增加你系统的物理内存或交换内存,或者
  • 一个一个地创建和处理 Fs<n> 数组,而不是同时把它们都放在内存里
1

每当你看到一段代码,只有一个字符不同的时候,你就应该考虑使用循环来简化代码。在你的情况中,你有一些数据其实并没有被使用到,这样的做法是不太合理的。你的工作流程基本上是:

  • 获取一个 grain_size_array(粒度大小数组)
  • 对这个 grain_size_array 应用一个掩码
  • 把这个掩码加到一个占位符(Fs)里
  • 处理掉这个掩码和 grain_size_array

从代码的角度来看,你需要的东西大概是这样的:

g_pro_1 = load() # however you get that
Fs = np.zeros_like(g_pro_1, dtype = float)
Fs_tmp = np.zeros_like(g_pro_1, dtype = float)
for i in range(10):
    g_pro = load() # whatever
    grain_size_array = load() # whatever
    np.putmask(Fs_tmp, np.logical_and(grain_size_array > 0.0000625, grain_size_array <= 0.002), g_pro_1)
    Fs += Fs_tmp

撰写回答