【问题标题】:How to add "order within group" column in pandas?如何在熊猫中添加“组内订单”列?
【发布时间】:2015-08-24 23:52:59
【问题描述】:

获取以下数据框:

import pandas as pd
df = pd.DataFrame({'group_name': ['A','A','A','B','B','B'],
                   'timestamp': [4,6,1000,5,8,100],
                   'condition': [True,True,False,True,False,True]})

我要添加两列:

  1. 行在其组中的顺序
  2. 每个组内condition 列的滚动总和

我知道我可以通过自定义应用来做到这一点,但我想知道是否有人有任何有趣的想法? (当有很多组时,这也很慢。)这是一个解决方案:

def range_within_group(input_df):
    df_to_return = input_df.copy()
    df_to_return = df_to_return.sort('timestamp')
    df_to_return['order_within_group'] = range(len(df_to_return))
    df_to_return['rolling_sum_of_condition'] = df_to_return.condition.cumsum()
    return df_to_return

df.groupby('group_name').apply(range_within_group).reset_index(drop=True)

【问题讨论】:

  • 还可以使用rank()根据时间戳获取订单(又名排名)。如果需要,还可以为您提供处理关系的方法。

标签: python pandas


【解决方案1】:

GroupBy.cumcount 会:

将每个组中的每个项目编号从 0 到该组的长度 - 1。

这么简单:

>>> gr = df.sort('timestamp').groupby('group_name')
>>> df['order_within_group'] = gr.cumcount()
>>> df['rolling_sum_of_condition'] = gr['condition'].cumsum()

【讨论】:

  • 但是按照哪个顺序呢?为什么要专门按照时间戳的顺序来排序呢?
  • @AmiTavory 在groupby 之前添加了.sort。现在开心吗?
  • 即使假设groupby 是稳定的(即保持顺序),假设排序是Theta(n log(n))(即,超线性),将每个组单独排序更有效。
  • @AmiTavory 所有这些解决方案都是完全矢量化的或在 cython 中。在任何真实数据集上使用 apply(即使使用快速 lambda)都会慢几个数量级。因为 apply 本质上是一个 python 循环。
  • @AmiTavory 所以,我实际上会说不仅与排序算法(相对于 argsort 的摊销成本)线性相关,而且实际上与组数相关。例如。对 1M 行进行一些快速测试。 1000组时间差不多!但是有 100000 个组,排序方法要快得多。因此,当实现算法的成本较高或在另一个复杂性稍差的算法上常数较小时,算法并不总是获胜。
猜你喜欢
  • 1970-01-01
  • 2022-01-06
  • 2019-02-10
  • 2021-07-27
  • 2018-03-02
  • 2020-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多