如何为DataFrame按ID分组生成连续行差值的移位列?
问题解决:按ID分组生成移位拼接列
给定一个包含A(时间序列)、B(ID)、C(利用率)列的DataFrame,需要按ID分组,根据组内时间序列长度生成col1、col2等新列。核心需求是:
col1为当前行C值与下一行C值拼接(如100-80),组内最后一行的col1直接取当前C值col2对应下一行的col1值,以此类推,无对应值的位置填充NaN
示例数据说明
原数据(简化结构):
A B C Jan-21 1 100 Feb-21 1 80 Mar-21 1 70 Apr-21 1 60 May-21 1 40 Mar-21 2 200 Apr-21 2 100 May-21 2 50
期望输出:
ID Period OS col1 col2 col3 col4 1 Jan-21 100 100-80 80-70 70-60 60-40 1 Feb-21 80 80-70 70-60 60-40 40 1 Mar-21 70 70-60 60-40 40 NaN 1 Apr-21 60 60-40 40 NaN NaN 1 May-21 40 40 NaN NaN NaN 2 Mar-21 200 200-100 100-50 50 NaN 2 Apr-21 100 100-50 50 NaN NaN 2 May-21 50 50 NaN NaN NaN
解决方案代码
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'A': ['Jan-21', 'Feb-21', 'Mar-21', 'Apr-21', 'May-21', 'Mar-21', 'Apr-21', 'May-21'], 'B': [1,1,1,1,1,2,2,2], 'C': [100,80,70,60,40,200,100,50] }) def process_group(group): group_len = len(group) # 生成所有移位后的C值序列 shifted_c = [group['C'].shift(-i) for i in range(group_len)] # 逐个生成col1到coln col_list = [] for idx in range(group_len): if idx == group_len - 1: # 最后一行直接取当前C值 new_col = group['C'].astype(str).rename(f'col{idx+1}') else: # 拼接当前C与下一个移位后的C值 new_col = (group['C'].astype(str) + '-' + shifted_c[idx+1].astype(str)).rename(f'col{idx+1}') col_list.append(new_col) # 合并所有生成的列 return pd.concat(col_list, axis=1) # 按ID分组处理并合并回原数据 result_cols = df.groupby('B', group_keys=False).apply(process_group) final_df = pd.concat([df, result_cols], axis=1) # 重命名列匹配示例格式 final_df = final_df.rename(columns={'B':'ID', 'A':'Period', 'C':'OS'}) print(final_df)
代码逻辑说明
- 分组处理:通过
groupby('B')按ID拆分数据,对每个组单独生成目标列 - 移位序列生成:用
shift(-i)获取当前行之后第i行的C值,构建完整的移位列表 - 列值拼接:
- 非最后一行:将当前C值与下一行C值拼接为
X-Y格式 - 最后一行:直接保留当前C值
- 非最后一行:将当前C值与下一行C值拼接为
- 合并输出:将生成的
col1至coln合并回原DataFrame,自动补全无对应值的NaN
内容的提问来源于stack exchange,提问作者Asit
相关产品推荐
相关产品推荐

