【问题标题】:Efficient pandas grouby + nunique rolling calculation高效的 p​​andas groupby + nunique 滚动计算
【发布时间】:2022-01-26 00:56:54
【问题描述】:

我正在尝试构建一种可扩展的方法来计算修改某个文件的唯一成员的数量,直到并包括最新的 modified_date。 unique_member_until_now 列包含每个文件的预期结果。

import pandas as pd
from pandas import Timestamp

# Example Dataset

df = pd.DataFrame({'File': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'C', 'C', 'C'],
 'Member': ['X', 'X', 'Y', 'X', 'Y', 'Y', 'X', 'Z', 'Y', 'X', 'Y', 'X'],
 'modified_date': [Timestamp('2021-11-25 00:00:00'),
  Timestamp('2021-11-28 00:00:00'),
  Timestamp('2021-12-14 00:00:00'),
  Timestamp('2021-10-17 00:00:00'),
  Timestamp('2021-11-01 00:00:00'),
  Timestamp('2021-11-04 00:00:00'),
  Timestamp('2021-11-16 00:00:00'),
  Timestamp('2021-12-16 00:00:00'),
  Timestamp('2021-12-29 00:00:00'),
  Timestamp('2021-10-30 00:00:00'),
  Timestamp('2021-11-23 00:00:00'),
  Timestamp('2021-12-17 00:00:00')],
 'unique_member_until_now': [1, 1, 2, 1, 2, 2, 2, 3, 3, 1, 2, 2]})

df.groupby("File")["Member"].transform('nunique') 当然没有给出预期的结果

当前的方法是遍历每个组和组中的每条记录,但我确信在处理数百万行时,这种方法效率极低且速度很慢。

【问题讨论】:

    标签: python pandas pandas-groupby rolling-computation


    【解决方案1】:

    一种有效的方法是计算 File+Member 列上的(非)duplicated,然后是 groupby File 和 cumsum

    (~df[['File', 'Member']].duplicated()).groupby(df['File']).cumsum()
    

    另存为列:

    df['unique_member_until_now'] = (~df[['File', 'Member']].duplicated()).groupby(df['File']).cumsum()
    

    输出:

       File Member modified_date  unique_member_until_now
    0     A      X    2021-11-25                        1
    1     A      X    2021-11-28                        1
    2     A      Y    2021-12-14                        2
    3     B      X    2021-10-17                        1
    4     B      Y    2021-11-01                        2
    5     B      Y    2021-11-04                        2
    6     B      X    2021-11-16                        2
    7     B      Z    2021-12-16                        3
    8     B      Y    2021-12-29                        3
    9     C      X    2021-10-30                        1
    10    C      Y    2021-11-23                        2
    11    C      X    2021-12-17                        2
    

    【讨论】:

    • 很好...因为这样可以避免apply ;)
    • @richardec 我刚刚进行了一些测试,它比 apply 快 1.5-2 倍,不过你的逻辑是正确的 (+1) ;)
    【解决方案2】:

    您可以按File分组,然后使用is_duplicated(与~相反)+cumsum

    df['unique_member_until_now'] = df.groupby('File').apply(lambda g: (~g['Member'].duplicated()).cumsum()).droplevel(0)
    

    输出:

    >>> df
       File Member modified_date  unique_member_until_now
    0     A      X    2021-11-25                        1
    1     A      X    2021-11-28                        1
    2     A      Y    2021-12-14                        2
    3     B      X    2021-10-17                        1
    4     B      Y    2021-11-01                        2
    5     B      Y    2021-11-04                        2
    6     B      X    2021-11-16                        2
    7     B      Z    2021-12-16                        3
    8     B      Y    2021-12-29                        3
    9     C      X    2021-10-30                        1
    10    C      Y    2021-11-23                        2
    11    C      X    2021-12-17                        2
    

    【讨论】:

      猜你喜欢
      • 2019-09-22
      • 2018-08-24
      • 1970-01-01
      • 2017-05-29
      • 2020-04-11
      • 2021-09-23
      • 2023-02-24
      • 1970-01-01
      • 2019-11-15
      相关资源
      最近更新 更多