在Pandas中从多维面板数据生成ratio滞后变量
生成多维面板数据的滞后变量解决方案
我有一组多维面板数据,其中一个personal_id对应多个application_id,每个application_id最多包含22行重复数据,且application_id对personal_id唯一。需要为每个personal_id生成ratio的5个滞后变量(ratio_lag1到ratio_lag5)。
样本数据
| personal_id | application_id | creation_timestamp | ratio |
|---|---|---|---|
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 |
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 |
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 |
| 14de | 0ae0 | 2023-10-03 14:46:42.378078 | 0.338710 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 |
| 14de | 9672 | 2023-08-30 13:01:55.107695 | 0.290323 |
| 14de | 2500 | 2023-08-16 15:32:49.080397 | 0.203226 |
| 14de | 2500 | 2023-08-16 15:32:49.080397 | 0.203226 |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 |
| 2b33 | 8d85 | 2023-06-13 08:06:17.106777 | 0.000000 |
| 2b33 | 8d85 | 2023-06-13 08:06:17.106777 | 0.000000 |
期望输出
| personal_id | application_id | creation_timestamp | ratio | ratio_lag1 | ratio_lag2 |
|---|---|---|---|---|---|
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 | 0.000000 | nan |
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 | 0.000000 | nan |
| 2b33 | 69c0 | 2023-11-20 05:32:26.691008 | 0.057774 | 0.000000 | nan |
| 14de | 0ae0 | 2023-10-03 14:46:42.378078 | 0.338710 | 0.161290 | 0.290323 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 | 0.290323 | 0.203226 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 | 0.290323 | 0.203226 |
| 14de | ac60 | 2023-09-11 15:15:20.924994 | 0.161290 | 0.290323 | 0.203226 |
| 14de | 9672 | 2023-08-30 13:01:55.107695 | 0.290323 | 0.203226 | 0.080645 |
| 14de | 2500 | 2023-08-16 15:32:49.080397 | 0.203226 | 0.080645 | nan |
| 14de | 2500 | 2023-08-16 15:32:49.080397 | 0.203226 | 0.080645 | nan |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 | nan | nan |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 | nan | nan |
| 14de | db26 | 2023-08-01 10:40:48.473828 | 0.080645 | nan | nan |
| 2b33 | 8d85 | 2023-06-13 08:06:17.106777 | 0.000000 | nan | nan |
| 2b33 | 8d85 | 2023-06-13 08:06:17.106777 | 0.000000 | nan | nan |
解决方案(Python Pandas实现)
核心思路是先对每个用户的申请按时间降序排序,提取唯一申请的ratio值生成滞后变量,再将滞后变量映射回原始数据的所有行。
import pandas as pd # 读取原始数据(这里用样本数据举例) data = pd.DataFrame({ 'personal_id': ['2b33', '2b33', '2b33', '14de', '14de', '14de', '14de', '14de', '14de', '14de', '14de', '14de', '14de', '2b33', '2b33'], 'application_id': ['69c0', '69c0', '69c0', '0ae0', 'ac60', 'ac60', 'ac60', '9672', '2500', '2500', 'db26', 'db26', 'db26', '8d85', '8d85'], 'creation_timestamp': ['2023-11-20 05:32:26.691008', '2023-11-20 05:32:26.691008', '2023-11-20 05:32:26.691008', '2023-10-03 14:46:42.378078', '2023-09-11 15:15:20.924994', '2023-09-11 15:15:20.924994', '2023-09-11 15:15:20.924994', '2023-08-30 13:01:55.107695', '2023-08-16 15:32:49.080397', '2023-08-16 15:32:49.080397', '2023-08-01 10:40:48.473828', '2023-08-01 10:40:48.473828', '2023-08-01 10:40:48.473828', '2023-06-13 08:06:17.106777', '2023-06-13 08:06:17.106777'], 'ratio': [0.057774, 0.057774, 0.057774, 0.338710, 0.161290, 0.161290, 0.161290, 0.290323, 0.203226, 0.203226, 0.080645, 0.080645, 0.080645, 0.000000, 0.000000] }) # 1. 将时间列转换为datetime类型,确保排序正确 data['creation_timestamp'] = pd.to_datetime(data['creation_timestamp']) # 2. 提取每个personal_id+application_id的唯一数据(因为同一application_id的ratio一致) unique_apps = data.drop_duplicates(subset=['personal_id', 'application_id']).copy() # 3. 按personal_id分组,每组内按creation_timestamp降序排序(最新的申请在前) unique_apps = unique_apps.sort_values(by=['personal_id', 'creation_timestamp'], ascending=[True, False]) # 4. 生成5个滞后变量:lag1是下一个(更早的)申请的ratio,以此类推 for i in range(1, 6): unique_apps[f'ratio_lag{i}'] = unique_apps.groupby('personal_id')['ratio'].shift(i) # 5. 将滞后变量合并回原始数据,同一个application_id的所有行共享滞后值 result = pd.merge(data, unique_apps[['personal_id', 'application_id'] + [f'ratio_lag{i}' for i in range(1,6)]], on=['personal_id', 'application_id'], how='left') # 查看结果(这里只展示前两列滞后变量,和期望输出一致) print(result[['personal_id', 'application_id', 'creation_timestamp', 'ratio', 'ratio_lag1', 'ratio_lag2']])
代码说明:
- 时间转换:确保时间列是datetime类型,避免字符串排序错误。
- 去重处理:同一
application_id的所有行ratio值相同,只需保留一行生成滞后变量,减少计算量。 - 分组排序:按用户分组后,将最新的申请排在最前面,这样
shift(i)就能取到第i个更早的申请的ratio。 - 合并映射:把生成的滞后变量合并回原始数据,保证同一
application_id的所有行都有相同的滞后值。
内容的提问来源于stack exchange,提问作者Alex Günsberg
相关产品推荐
相关产品推荐

