当前位置: 首页 > 知识库问答 >
问题:

PANDS Groupby Agg功能不会减少

钦德佑
2023-03-14

我正在使用一个聚合函数,我已经在我的工作中使用了很长时间了。其思想是,如果传递给函数的序列长度为1(即组只有一个观察值),则返回该观察值。如果传递的序列长度大于1,则在列表中返回观察值。

对一些人来说,这可能看起来很奇怪,但这不是一个X,Y问题,我有充分的理由想做这个与这个问题无关的事情。

这是我一直在使用的函数:

def MakeList(x):
    """ This function is used to aggregate data that needs to be kept distinc within multi day 
        observations for later use and transformation. It makes a list of the data and if the list is of length 1
        then there is only one line/day observation in that group so the single element of the list is returned. 
        If the list is longer than one then there are multiple line/day observations and the list itself is 
        returned."""
    L = x.tolist()
    if len(L) > 1:
        return L
    else:
        return L[0]

现在由于某种原因,在我正在处理的当前数据集中,我得到了一个值错误,声明函数不减少。下面是一些测试数据和我正在使用的剩余步骤:

import pandas as pd
DF = pd.DataFrame({'date': ['2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02',
                            '2013-04-02'],
                    'line_code':   ['401101',
                                    '401101',
                                    '401102',
                                    '401103',
                                    '401104',
                                    '401105',
                                    '401105',
                                    '401106',
                                    '401106',
                                    '401107'],
                    's.m.v.': [ 7.760,
                                25.564,
                                25.564,
                                9.550,
                                4.870,
                                7.760,
                                25.564,
                                5.282,
                                25.564,
                                5.282]})
DFGrouped = DF.groupby(['date', 'line_code'], as_index = False)
DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList})

在调试时,我使用了一条print语句,其效果是printlprint x.index,输出如下:

[7.7599999999999998, 25.564]
Int64Index([0, 1], dtype='int64')
[7.7599999999999998, 25.564]
Int64Index([0, 1], dtype='int64')

出于某种原因,agg似乎将序列传递给函数两次。据我所知,这根本不正常,大概是我的功能没有减少的原因。

例如,如果我编写这样的函数:

def test_func(x):
    print x.index
    return x.iloc[0]

运行时不会出现问题,打印语句如下:

DF_Agg = DFGrouped.agg({'s.m.v.' : test_func})

Int64Index([0, 1], dtype='int64')
Int64Index([2], dtype='int64')
Int64Index([3], dtype='int64')
Int64Index([4], dtype='int64')
Int64Index([5, 6], dtype='int64')
Int64Index([7, 8], dtype='int64')
Int64Index([9], dtype='int64')

这表示每个组只作为一个系列传递给函数一次。

有人能帮我理解为什么这失败了吗?我已经成功地在我使用的许多数据集中使用了这个函数......

谢谢

共有2个答案

司马羽
2023-03-14

这是DataFrame中的一个错误功能。如果聚合器返回第一个组的列表,它将失败,并出现您提到的错误;如果它为第一个组返回一个非列表(非系列),它将正常工作。断开的代码位于groupby.py中:

def _aggregate_series_pure_python(self, obj, func):

    group_index, _, ngroups = self.group_info

    counts = np.zeros(ngroups, dtype=int)
    result = None

    splitter = get_splitter(obj, group_index, ngroups, axis=self.axis)

    for label, group in splitter:
        res = func(group)
        if result is None:
            if (isinstance(res, (Series, Index, np.ndarray)) or
                    isinstance(res, list)):
                raise ValueError('Function does not reduce')
            result = np.empty(ngroups, dtype='O')

        counts[label] = group.shape[0]
        result[label] = res

请注意,如果结果为None则为instance(res,list。您的选项包括:

>

自己做聚合,使用上面那样的代码,但没有错误的测试。

松英喆
2023-03-14

我真的无法解释原因,但根据我在pandas.DataFrame中的list的经验,它的工作并不那么好。

我通常使用tuple。这将起作用:

def MakeList(x):
    T = tuple(x)
    if len(T) > 1:
        return T
    else:
        return T[0]

DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList})

     date line_code           s.m.v.
0  2013-04-02    401101   (7.76, 25.564)
1  2013-04-02    401102           25.564
2  2013-04-02    401103             9.55
3  2013-04-02    401104             4.87
4  2013-04-02    401105   (7.76, 25.564)
5  2013-04-02    401106  (5.282, 25.564)
6  2013-04-02    401107            5.282

 类似资料:
  • 问题内容: 我的问题与jQuery方法有关。我无法使用成功参数。 这有效: 这不是: 在第一种情况下,我得到一个JavaScript警报窗口,该窗口使我知道调用的函数正在工作。我在第二个代码块中所做的所有更改都放在了。 这样做的目的是验证$ .ajax是否正在运行,以便在$ .ajax成功运行时可以在其中放置一些实际有用的代码。 问题答案: 在第二个示例中,除非您从服务器成功回电,否则将不会发生任

  • 问题内容: 据我了解,reduce函数带有一个列表和一个function 。然后,它在列表的前两个元素上调用该函数,然后使用下一个列表元素和上一个结果重复调用该函数。 因此,我定义了以下功能: 以下函数计算阶乘。 现在,这不应该给我吗?但是,它给出了。为什么呢 似乎也需要析因。但是,我需要了解原因。 有人可以解释为什么会发生这种情况以及解决方法吗? 我基本上想计算列表中所有条目的阶乘乘积。备份计划

  • 问题内容: 我知道在模板中我可以调用以表达式命名的函数,例如。但是如何为表达式命名函数呢? 问题答案: 您总是可以定义这样的功能:

  • 描述 (Description) LESS由列表函数组成,列表函数用于指定列表的长度和列表中值的位置。 下表列出了LESS中使用的List函数 - Sr.No. 功能说明 1 Length 它将以逗号或空格分隔的值列表作为参数。 2 Extract 它将返回列表中指定位置的值。

  • 我想知道是否有人知道一种很好的方法,可以使用Capybara/Browserstack/Cucumber按顺序启动各个浏览器堆栈测试。 我在使用Capybara时遇到了一些问题,因为browserstack不会在每次运行时都使用我的新功能进行更新,即使我关闭了浏览器,也不会更新,即:两次测试在browserstack中顺序启动,但使用相同的浏览器和操作系统设置。 摘要场景:运行登录测试假设我想测试

  • ::: hljs-center 一、会员商品功能介绍 ::: 1、选购开发者: 面向有用户分层运营需求的开发者,例如对普通用户、会员用户、高价值用户群体,在商品兑换上设置不同兑换价格,赋予用户尊享感/价格特权,并引导用户会员等级升级,适合促进用户会员转化、低等级会员升级、开展精细化商品运营的开发者使用。 2、功能说明: ==(1)自定义会员商品== 选择单个在售商品,并配置该商品的可兑换会员等级、