高效 pandas grouby + nunique 滚动计算
Efficient pandas grouby + nunique rolling calculation
我正在尝试构建一种可扩展的方法来计算已修改特定文件直至并包括最新 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')
当然没有给出预期的结果
当前的方法是迭代每个组和组中的每个记录,但我确信在处理数百万行时效率非常低且速度很慢。
您可以按 File
分组,然后使用 is_duplicated
(inverted with ~
) + 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
一种有效的方法是计算(非)duplicated
on the File+Member columns, then groupby
File and 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
我正在尝试构建一种可扩展的方法来计算已修改特定文件直至并包括最新 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')
当然没有给出预期的结果
当前的方法是迭代每个组和组中的每个记录,但我确信在处理数百万行时效率非常低且速度很慢。
您可以按 File
分组,然后使用 is_duplicated
(inverted with ~
) + 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
一种有效的方法是计算(非)duplicated
on the File+Member columns, then groupby
File and 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