【问题标题】:df.groupby() - how to aggregate data where order of grouped data is important?df.groupby() - 如何聚合分组数据顺序很重要的数据?
【发布时间】:2019-08-23 13:11:56
【问题描述】:

当分组数据的顺序很重要时,我如何聚合数据?(如果可以以优雅的矢量化方式完成,则可以加分)。如果这很清楚,让我用一个例子来解释。


假设我在df 中有数据:

id    month              value
------------------------------
001   2019-01-01 (Jan)     111
001   2019-02-01 (Feb)     222
001   2019-03-01 (Mar)     333

002   2019-01-01 (Jan)       0
002   2019-02-01 (Feb)       0
002   2019-03-01 (Mar)      25

...   ...                  ...

999   2019-01-01 (Jan)     800
999   2019-02-01 (Feb)     600
999   2019-03-01 (Mar)     400

我可以使用groupby 聚合每个id 上的数据:

df.groupby('id')['value'].agg([numpy.sum, numpy.mean])

无论我使用numpy.sumnumpy.meannumpy.max等作为聚合函数,分组的孤立数组的顺序都没有关系(例如[111, 222, 333]代表id=001)-结果总是一样的。


但是,有些聚合的顺序确实很重要 - 例如,我可能想要计算:

  • 加权平均值(例如,如果较新的值具有更大的权重)
  • 从头到尾的更改(例如,Mar - Jan

目前,我遍历每个id,然后:

  1. 通过df[df['id']==id]过滤数据
  2. 获取月份值元组的列表,例如[(Jan,111), (Feb,222), (Mar,333)]
  3. 根据每个元组的第一个元素对列表进行排序,即'month'
  4. 执行聚合

例如,如果我只想找到 该排序数组的第一个元素和最后一个元素之间的差异,那么我会得到以下结果:

id    finish_minus_start
------------------------
001                  222
002                   25
...                  ...
999                 -400

当分组数据的顺序很重要时,如何聚合数据?

我可以通过使用矢量化而不是循环遍历每个id 来更有效地做到这一点吗?

【问题讨论】:

  • 也许这个解决方案有帮助:stackoverflow.com/questions/25995771/… 它计算一个先前的顺序来重新排列分组
  • @BCJuan - 谢谢 - 这看起来很有用。该解决方案将订购df,这样对于每个id,行将按'month' 排序。好的开始。但是你能确认在这个排序的df 上进行聚合时,这些行的顺序反映在传递给聚合函数的值中(例如,numpy.mean(x))吗?即,由于某种我无法理解的原因,孤立的值不会在幕后摇摆不定。
  • df.groupby('id').apply(lambda x: x.sort_values('month')) 这样的东西怎么样?
  • 我猜矢量化函数只适用于最常见的操作,对于其余的,我们必须使用:df.groupby('id').apply(lambda x: User_Defined_function(x))
  • @hacker315 - 你能再明确一点吗,因为我很难找到解决方案!假设我希望我的用户定义函数为 difference_between_first_and_last_elements(),我将如何定义该函数以为每个 id 返回单个值?即sorted_list[-1] - sorted_list[0].

标签: python pandas dataframe aggregate pandas-groupby


【解决方案1】:

我希望这就是您想要的。 您可以使用聚合并设置自己的功能。我从两个链接中举了一个例子 Summarizing and Grouping dataFirst and Last Functions 玩了一会儿。

df= df.set_index('date')
aggregations = {
    'value': lambda x: x.loc[x.index.max()] - x.loc[x.index.min()]
}
print(df.groupby('id').agg(aggregations))

【讨论】:

  • 目前,我认为这只是找到了value 列中第一个和最后一个元素之间的区别(很好),但我不能保证这些第一个和最后一个元素是由什么定义的在相应的month 列中(坏)-据我所知,它可能只是随机排序的。您能否修改您的答案,以使结果产生我在原始帖子底部显示的数据框?
  • 已编辑。如果我理解正确,应该是这样。您需要为此分配一个日期列,然后对其进行索引。
  • 非常感谢 - 这行得通 :) 虽然我在使用它时有点紧张,因为我没有正确理解发生了什么(尽管这取决于我对 lambda 函数的有限了解)。 lambda 函数如何知道如何处理 value 列 - 我没有看到它在 lambda 函数中的任何地方引用?
  • 只需将 lambda 视为单行函数。您可以尝试创建一个单独的函数来帮助您理解...... func_a(df): return x.loc[x.index.max()] 等......根据我对它的工作原理的理解......同样,数据帧 df 被扔进 func_a(df)。聚合字典有一个名为:“值”的键,值作为“值”列的函数结果,然后返回到聚合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-21
  • 2017-01-24
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多