【问题标题】:What could be the best way to bypass `MemoryError` in this case?在这种情况下,绕过“MemoryError”的最佳方法是什么?
【发布时间】:2018-05-14 20:12:22
【问题描述】:

我有两个相当大的numpy 数组。第一个是arr1,大小为(40, 40, 3580),第二个是arr2,大小为(3580, 50)。我想要实现的是

arr_final = np.sum(arr1[..., None]*arr2, axis = 2)

这样arr_final 的大小就是(40, 40, 50)。但是,在执行上述操作时,python 可能会缓存内部数组操作,因此我不断收到内存错误。有什么办法可以避免内部缓存并获得最终结果?我看过numexpr,但我不确定如何实现arr1[..., None]*arr2,然后sum 超过axis=2numexpr。任何帮助或建议将不胜感激。

【问题讨论】:

  • 您正在针对 (1,1,3580,50) 广播 (40,40,3580,1),生成 (40,40,3580,50) 数组。然后你会总结,减少到(40,40,50)。但是你仍然必须有足够的中间值。您可以尝试迭代大小为 50 的维度。一个大任务的 50 次循环在时间上应该是可以的。
  • 这个临时数组很大,但应该是 2GB 大,而不是 MemoryError 大。除非您的 dtype 是 object(在这种情况下:不要那样做),或者您使用的是 32 位 Python (dittp),或者您使用的是嵌入式平台(好吧,这是个问题)。它仍然值得尝试优化,但值得尝试弄清楚您是如何耗尽内存的。
  • 那种好像就是dot
  • arr1[:, None]*arr2 实际上不起作用。你的意思是arr1[..., None]*arr2
  • @user2357112 是的,它是arr1[..., None]*arr2

标签: python arrays numpy memory numexpr


【解决方案1】:

假设你的意思是np.sum(arr1[..., None]*arr2, axis = 2),用...而不是:,那么就是dot

arr3 = arr1.dot(arr2)

这应该比显式具体化arr1[..., None]*arr2 更有效,但我不知道它究竟分配了哪些中间体。

您也可以使用einsum 来表达计算。同样,这应该比显式实现arr1[..., None]*arr2 更有效,但我不知道它具体分配了什么。

arr3 = numpy.einsum('ijk,kl', arr1, arr2)

【讨论】:

  • 哇,这完美!我认为在这种情况下内存分配非常有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多