Pandas Groupby Agg 函数不减少
Posted
技术标签:
【中文标题】Pandas Groupby Agg 函数不减少【英文标题】:Pandas Groupby Agg Function Does Not Reduce 【发布时间】:2015-02-10 21:23:45 【问题描述】:我正在使用我在工作中使用了很长时间的聚合函数。这个想法是,如果传递给函数的系列长度为 1(即该组只有一个观察值),则返回该观察值。如果传递的 Series 的长度大于 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]
现在由于某种原因,使用我正在处理的当前数据集,我得到一个 ValueError ,指出该函数没有减少。这是一些测试数据和我正在使用的剩余步骤:
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 语句设置为 print L
和 print 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')
这表明每个组只作为一个系列传递给函数一次。
谁能帮我理解为什么会失败?我已经在我使用的许多数据集中成功地使用了这个函数......
谢谢
【问题讨论】:
如果你的函数有时返回一个列表,有时返回一个值,pandas 可能会感到困惑,因为这两种情况会使用不同的 dtype。最好不要那样做。两次调用行为可能与here 为apply
描述的问题有关:它在第一组上调用该函数两次,以检查该函数是否改变了现有数据。
嗯....我应该尝试设置为 object dtype。
最奇怪的是,我一直在重用这段代码,没有任何问题。我知道 apply 和 transform 传递不同的数据包,因此很难从打印语句中确定发生了什么,但是 agh 相当简单。你能重现错误吗?
我可以重现错误,但我无法重现它工作的非错误。您的 test_func
确实减少了,因为它只返回一个值。您是否有一个聚合函数返回列表的工作示例?这对你有用吗?
一个有趣的解决方案是返回tuple(L)
而不是L
【参考方案1】:
我无法真正解释为什么,但根据我的经验,list
在pandas.DataFrame
中并没有那么好用。
我通常改用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
【讨论】:
这与tuple
类型是不可变的,因此是可散列的,而 list
不是。
可能!但是从“不聚合”的角度来看,这些概念是相同的,因此无法猜测某些内容不起作用,因为您使用的是列表而不是元组。不错的收获!【参考方案2】:
这是 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
请注意if result is None
和isinstance(res, list
。
您的选择是:
伪造 groupby().agg(),所以它看不到第一组的列表,或者
自己进行聚合,使用类似上面的代码但没有错误的测试。
【讨论】:
如另一个答案tuple
中所解释的那样可以正常工作。准确地说,上述函数不检查对象是否为tuple
。错误或功能 - 您决定!以上是关于Pandas Groupby Agg 函数不减少的主要内容,如果未能解决你的问题,请参考以下文章
pandas使用groupby函数进行分组聚合并使用agg函数将每个分组特定变量对应的多个内容组合到一起输出(merging content within a specific column of g
python处理数据的风骚操作[pandas 之 groupby&agg]
pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用agg函数计算每个分组不同数值变量的聚合统计值agg参数为字典指定不同变量的聚合计算统计量的形式
python使用pandas中的groupby函数和agg函数计算每个分组数据的两个分位数(例如百分之10分位数和百分之90分位数)
pandas使用groupby函数按照多个分组变量进行分组聚合统计使用agg函数计算分组的多个统计指标(grouping by multiple columns in dataframe)