我有一个交易数据,包含三列,分别包括 user_account、transaction_id 和 transaction_date。我想根据 user_account 和 24 小时时间段计算不同 transaction_id 的滚动累积计数。下面显示了一个示例。
数据 |用户帐户 | transaction_date |transaction_id |cumulative_distinct_count | -------- | -------- | -------- | -------- | | X0119989 | 2024-04-03 14:03:46| G0000006 |1 | | X0119989 | 2024-04-22 22:35:16| G0000005 |1 | | X0119989 | 2024-04-22 22:56:43| G0000004 |2 | | X0119989 | 2024-04-25 20:24:36| G0000003 |1 | | X0119989 | 2024-04-25 21:02:54| G0000002 |2 | | X0119989 | 2024-04-25 21:52:13| G0000001 |3 | | X0119999 | 2024-04-01 22:44:05| G0000012 |1 | | X0119999 | 2024-04-01 22:46:00| G0000011 |2 | | X0119999 | 2024-04-01 22:54:21| G0000010 |3 | | X0119999 | 2024-04-01 22:59:33| G0000009 |4 | | X0119999 | 2024-04-01 23:07:46| G0000008 |5 | | X0119999 | 2024-04-02 00:02:20| G0000007 |6 |
上表中,第一行的事务id“G0000006”在“cumulative_distinct_count”列中为1,是因为在“2024/4/3 14:03”的过去24小时内除了其本身之外没有其他事务id发生:46"。第三行的交易id“G0000004”有2,因为在“2024/4/22 22:56:43”的过去24小时内有两笔交易,包括“G0000004”和“G0000005”发生了。我想做的是计算列“cumulative_distinct_count”。
我目前使用 pandas 的 apply 方法找到了一个不需要的解决方案。代码如下所示。
def count_unique_id(x):
condition = (data['datetime'].between(x['datetime'] - dt.timedelta(days=1), x['datetime'])) & (data['user_account'] == x['user_account'])
return g[condition]['transaction_id'].nunique()
g['count_unique_id'] = g.swifter.apply(count_unique_id, axis=1)
由于数据量超过 300 万行,上述解决方案对我来说花费了太多时间。我正在寻找其他可以运行得更快的解决方案。
提前致谢。
一种方法如下:
import pandas as pd
from datetime import timedelta
data = {
'user_account': ['user1', 'user1', 'user1', 'user2', 'user2', 'user2'],
'transaction_id': ['G0000006', 'G0000005', 'G0000004', 'G0000010', 'G0000009', 'G0000008'],
'transaction_date': [
'2024/04/03 14:03:46',
'2024/04/03 18:20:00',
'2024/04/22 22:56:43',
'2024/04/22 14:03:46',
'2024/04/23 18:20:00',
'2024/04/24 22:56:43'
]
}
df = pd.DataFrame(data)
df['transaction_date'] = pd.to_datetime(df['transaction_date'])
df = df.sort_values(by=['user_account', 'transaction_date'])
def rolling_distinct_count(group):
result = []
for i in range(len(group)):
start_time = group['transaction_date'].iloc[i] - timedelta(days=1)
end_time = group['transaction_date'].iloc[i]
count = group[(group['transaction_date'] > start_time) & (group['transaction_date'] <= end_time)]['transaction_id'].nunique()
result.append(count)
return pd.Series(result, index=group.index)
df['cumulative_distinct_count'] = df.groupby('user_account').apply(rolling_distinct_count).reset_index(level=0, drop=True)
print(df)
这给出了
user_account transaction_id transaction_date cumulative_distinct_count
0 user1 G0000006 2024-04-03 14:03:46 1
1 user1 G0000005 2024-04-03 18:20:00 2
2 user1 G0000004 2024-04-22 22:56:43 1
3 user2 G0000010 2024-04-22 14:03:46 1
4 user2 G0000009 2024-04-23 18:20:00 1
5 user2 G0000008 2024-04-24 22:56:43 1