如何在熊猫中添加“组内订单”列?

exp*_*rer 5 python pandas

获取以下数据框:

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]})
Run Code Online (Sandbox Code Playgroud)

我想添加两列:

  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)
Run Code Online (Sandbox Code Playgroud)

beh*_*uri 7

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()
Run Code Online (Sandbox Code Playgroud)

  • @AmiTavory 所有这些解决方案都是完全矢量化的或在 cython 中。在任何真实数据集上使用 apply(即使使用快速 lambda)也会慢几个数量级。由于 apply 本质上是一个 python 循环。 (2认同)
  • @AmiTavory 所以,我实际上会说线性相关不仅与排序算法(相对于 argsort 的摊销成本),而且真的与组数线性相关。例如,对 1M 行进行一些快速测试。1000 组时间差不多!但是对于 100000 个组,排序方法要快得多。因此,当实现算法的成本较高或常数较小的另一个复杂性稍差的算法时,算法并不总是获胜。 (2认同)