如何按日期重新排序Pandas DataFrame中的ID列(保留行数)
问题描述
现有一个已按日期降序排序的Pandas DataFrame,其中ID列未按升序排列(同一日期对应多个不同ID),原始数据如下:
ID Date 1 2022-05-13 1 2022-05-13 1 2022-05-13 3 2022-05-13 3 2022-05-13 3 2022-05-13 3 2022-05-13 16 2022-07-14 16 2022-07-14 16 2022-07-14 2 2022-07-14 2 2022-07-14 2 2022-07-14 2 2022-07-14 2 2022-07-14 2 2022-07-14 9 2022-08-11 9 2022-08-11
需要重新排列ID列,使ID按升序排列,同时保留每个原始ID对应的行数,最终结果如下:
ID Date 1 2022-05-13 1 2022-05-13 1 2022-05-13 2 2022-05-13 2 2022-05-13 2 2022-05-13 2 2022-05-13 3 2022-07-14 3 2022-07-14 3 2022-07-14 4 2022-07-14 4 2022-07-14 4 2022-07-14 4 2022-07-14 4 2022-07-14 4 2022-07-14 5 2022-08-11 5 2022-08-11
解决方案
简洁实现方式
利用Pandas的groupby结合factorize方法,在每个日期分组内对原始ID进行连续升序编码,同时保留原有的行数分布:
import pandas as pd # 构造示例DataFrame(实际使用时替换为你的数据) data = { 'ID': [1,1,1,3,3,3,3,16,16,16,2,2,2,2,2,2,9,9], 'Date': ['2022-05-13']*7 + ['2022-07-14']*9 + ['2022-08-11']*2 } df = pd.DataFrame(data) # 按日期分组,对每组内的ID进行连续升序编码(从1开始) df['ID'] = df.groupby('Date')['ID'].transform(lambda x: pd.factorize(x, sort=False)[0] + 1) # 输出结果 print(df)
代码解释
groupby('Date'):将数据按日期分组,确保只在同一日期内调整ID顺序pd.factorize(x, sort=False):对每组内的唯一ID进行编码,返回从0开始的整数序列(sort=False保证按原始出现顺序编码)+1:将编码从0起始转为1起始,符合需求中的升序ID格式
分步实现(适合理解逻辑)
如果需要更清晰的步骤拆解,可以按以下方式操作:
- 按日期分组,提取每组内的唯一原始ID
- 为每组内的唯一ID分配连续的新ID
- 创建原始ID到新ID的映射字典
- 用映射字典替换原始DataFrame中的ID列
import pandas as pd # 构造示例DataFrame data = { 'ID': [1,1,1,3,3,3,3,16,16,16,2,2,2,2,2,2,9,9], 'Date': ['2022-05-13']*7 + ['2022-07-14']*9 + ['2022-08-11']*2 } df = pd.DataFrame(data) # 1. 按日期分组,获取每组内的唯一ID并分配新ID grouped_unique = df.groupby('Date')['ID'].unique().reset_index() grouped_unique['new_ID_base'] = grouped_unique.groupby('Date').cumcount() + 1 # 2. 构建(ID, Date)到新ID的映射 id_map = {} for _, row in grouped_unique.iterrows(): date = row['Date'] base_id = row['new_ID_base'] for idx, orig_id in enumerate(row['ID']): id_map[(date, orig_id)] = base_id + idx # 3. 替换原始ID列 df['ID'] = df.apply(lambda x: id_map[(x['Date'], x['ID'])], axis=1) print(df)
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

