基于ID和随访月份为多行DataFrame添加时间点列
为DataFrame添加Timepoint列的解决方案
原始DataFrame
| ID | Follow up month | Value-x | value -y |
|---|---|---|---|
| 1 | 0 | 12 | 12 |
| 1 | 0 | 11 | 14 |
| 2 | 0 | 10 | 11 |
| 2 | 3 | 11 | 0 |
| 2 | 0 | 12 | 1 |
| 1 | 3 | 13 | 12 |
| 2 | 3 | 11 | 5 |
预期结果
| ID | Follow up month | Value-x | value -y | Timepoint |
|---|---|---|---|---|
| 1 | 0 | 12 | 12 | 1 |
| 1 | 0 | 11 | 14 | 1 |
| 2 | 0 | 10 | 11 | 1 |
| 2 | 3 | 11 | 0 | 2 |
| 2 | 0 | 12 | 1 | 1 |
| 1 | 3 | 13 | 12 | 2 |
| 2 | 3 | 11 | 5 | 2 |
问题分析
你之前用cumcount的思路不对,因为cumcount是给每个(ID, Follow up month)分组内的行逐行编号,但需求是同一ID下,相同的Follow up month对应同一个Timepoint,不同的Follow up month按顺序分配1、2这类连续编号。
解决方法
方法1:使用rank函数(推荐)
按ID分组后,对Follow up month做密集排序,直接生成对应Timepoint:
import pandas as pd # 构造原始数据 df = pd.DataFrame({ 'ID': [1,1,2,2,2,1,2], 'Follow up month': [0,0,0,3,0,3,3], 'Value-x': [12,11,10,11,12,13,11], 'value -y': [12,14,11,0,1,12,5] }) # 添加Timepoint列 df['Timepoint'] = df.groupby('ID')['Follow up month'].rank(method='dense', ascending=True).astype(int)
方法2:使用factorize函数
按ID分组后,对组内的Follow up month做因子化处理,生成连续编号:
df['Timepoint'] = df.groupby('ID')['Follow up month'].transform( lambda x: pd.factorize(x.sort_values())[0] + 1 )
两种方法都能得到符合预期的结果:同一ID下,Follow up month=0对应Timepoint=1,Follow up month=3对应Timepoint=2,且同一分组内的所有行Timepoint完全一致。
内容的提问来源于stack exchange,提问作者Hedayat
相关产品推荐
相关产品推荐

