Python 为什么我会有这样的回忆?

Python 为什么我会有这样的回忆?,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我遇到了一个奇怪的记忆错误,我不明白它为什么会在那里。代码示例: # 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['ba

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

# 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']
会导致
内存错误崩溃,但是:如果我改为这样做:

blah['temp'] = blah[['bat','foo']].groupby('bat').transform(sum)
blah['test'] = np.where(blah.cat == 'A',
    blah['temp'],
    0)
一切正常。我的猜测是,
np.where
.groupby()

然而,如果我最初的
废话
只有列
'foo',cat',bat'
(因此没有列
不直接涉及代码的失败部分),那么第一种方法也可以,所以这让我更加困惑

这是怎么回事

blah['test'] = np.where(blah['cat'] == 'A',
    blah[['bat','foo']].groupby('bat')['bat'].transform(sum),
    0)
请注意,我在
groupby('bat')
的末尾添加了一个
['bat']


我的基本原理是,您的python正在命中MemoryError,因为它试图对数据帧中的所有内容进行求和,因为它没有明确定义要求和的内容。代码的第一部分根本不正确。如果减少数据帧大小,您将得到

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)

应该有帮助。

旁注/可能相关:使用
'sum'
intead of
sum
,您应该避免使用Python内置的Pandas/NumPy对象。但是为什么,@jpp?使用内置函数不是会减少开销吗?@ayorgo,不是在NumPy的情况下:。@jpp是的,“避免使用Python内置函数”在这里肯定是正确的,但我相信传递
sum
映射到NumPy ufunc。请参见
pandas.core.base.SelectionMixin
SelectionMixin.\u内置\u table.get(sum,sum)
@BradSolomon,Nice,我不知道!虽然我认为在一般情况下使用字符串是一种很好的做法。该映射似乎是一个实现细节?我的理解是,它将
.transform()
中的函数应用于数据帧中不在
.groupby()
变量列表中的任何对象,因此当我说
blah[[['bat',foo']]
时,它对每个
bat
组求和
foo
,这就是我想要的。在任何情况下,这如何解释行为上的差异?@KetilTveiten您并没有指定您想要的
总和
。您只是指定希望在
blah[['bat',foo']]
中保留哪些列,以及希望在
中分组哪些列。groupby('bat')
可以,但是groupby/sum在不在
np中时可以正常工作。在
中,这就是产生混淆的地方。@KetilTveiten它不能正常工作。您会注意到,您正在将整个数据帧放入现有的数据帧中,并且这些值将是incorrect@jezrael我认为首先限制变量会使用更少的内存(是吗?),这与我的实际用例有关。无论如何,这回答了我的问题。