【问题标题】:Why am I getting this MemoryError?为什么我会收到此 MemoryError?
【发布时间】:2019-05-14 17:10:31
【问题描述】:

我遇到了一个奇怪的MemoryError,我不明白它为什么会在那里。代码示例:

# some setup
import numpy as np
import pandas as pd
import random

blah = pd.DataFrame(np.random.random((100000,2)), columns=['foo','bar'])
blah['cat'] = blah.apply(lambda x: random.choice(['A','B']), axis=1)
blah['bat'] = blah.apply(lambda x: random.choice([0,1,2,3,4,5]), axis=1)

# the relevant part:
blah['test'] = np.where(blah.cat == 'A',
    blah[['bat','foo']].groupby('bat').transform(sum),
    0)

以这种方式分配blah['test'] 会导致MemoryError 崩溃,但是:如果我改为这样做:

blah['temp'] = blah[['bat','foo']].groupby('bat').transform(sum)
blah['test'] = np.where(blah.cat == 'A',
    blah['temp'],
    0)

一切正常。我的猜测是 np.where.groupby() 的交互方式导致了这种情况。

但是,如果我最初的 blah 只有列 'foo', 'cat', 'bat' (所以没有列 bar 不直接参与失败的代码部分),第一种方法也可以,所以这让我更加困惑。

这是怎么回事?

【问题讨论】:

  • 旁注/可能相关:使用'sum' 而不是sum,您应该避免将Python 内置函数与Pandas / NumPy 对象一起使用。
  • 但是为什么,@jpp?使用内建的开销不是更少吗?
  • @ayorgo,不是 NumPy:see here
  • @jpp 是的,“避免使用 Python 内置函数”在这里当然是正确的,但我相信传递 sum 映射到 NumPy ufunc。见pandas.core.base.SelectionMixinSelectionMixin._builtin_table.get(sum, sum)
  • @BradSolomon,很好,不知道!虽然我认为在一般情况中使用字符串是一种很好的做法。该映射似乎是一个实现细节?

标签: python pandas pandas-groupby


【解决方案1】:

您的代码的第一部分根本不正确。如果你减少数据框大小,你会得到

ValueError: Wrong number of items passed 1000, placement implies 1

这表明np.where 无法遍历由返回的单列数据帧

blah[['bat','foo']].groupby('bat').transform(sum)

并尝试将整个列放到blah['test'] 的每个元素中,这可能会提前为整个操作分配内存,从而导致MemoryError

将您的实现更改为

blah['test'] = np.where(blah.cat == 'A',
                        blah[['bat','foo']].groupby('bat')['foo'].transform(sum),
                        0)

应该有帮助。

【讨论】:

  • @jezrael 我认为首先限制变量会使用更少的内存(是吗?),这与我的实际用例有关。无论如何,这回答了我的问题。
【解决方案2】:
blah['test'] = np.where(blah['cat'] == 'A',
    blah[['bat','foo']].groupby('bat')['bat'].transform(sum),
    0)

请注意,我在groupby('bat') 的末尾添加了一个['bat']

我的理由是你的 python 遇到 MemoryError 是因为它试图 sum 数据框中的所有内容,因为它没有具体定义你想要的 sum

【讨论】:

  • 我的理解是,它将.transform() 中的函数应用于数据框中不在.groupby() 变量列表中的任何内容,所以当我说blah[['bat', 'foo']] 时,它总和foo对于每个bat 组,这就是我想要的。无论如何,这如何解释行为上的差异?
  • @KetilTveiten 你没有指定你想要sum 的内容。您只是指定您希望在 blah[['bat', 'foo']] 中保留哪些列以及您希望在 .groupby('bat') 中分组的列
  • 好的,但是当不在np.where 中时,groupby/sum 可以正常工作,这就是产生混淆的地方。
  • @KetilTveiten 它工作不正常。您会注意到您将整个数据框放入现有数据框中,并且值将不正确
猜你喜欢
  • 1970-01-01
  • 2020-02-24
  • 2013-12-09
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
相关资源
最近更新 更多