Pandas宽表转滑动窗口式长表(按季度偏移)技术求助
通用化Pandas多季度数据滑动窗口转换方案
问题背景
原始DataFrame结构如下:
ID Q1_rev Q1_transcnt Q2_rev Q2_transcnt Q3_rev Q3_transcnt Q4_rev Q4_transcnt 1 100 2 200 4 300 6 400 8 2 101 3 201 5 301 7 401 9
需求说明:
- 每个ID生成3行数据(由输入的8列转换而来)
- 每行包含连续2个季度的rev和transcnt数据(实际场景可扩展为4/5个季度等任意窗口大小)
- 后续行按1个季度的步长偏移列数据
用户尝试了以下代码但未得到预期结果:
s = 3 n = 2 cols = ['1st_rev','1st_transcnt','2nd_rev','2nd_transcnt'] output = pd.concat((df.iloc[:,0+i*s:6+i*s].set_axis(cols, axis=1) for i in range(int((df.shape[1]-(s*n))/n))), ignore_index=True, axis=0).set_index(np.tile(df.index,2))
通用解决方案
核心思路是先拆分ID列与季度数据列,通过滑动窗口的方式为每个ID截取连续N个季度的数据集,自动处理列索引和命名,最后合并所有结果。
代码实现
import pandas as pd def sliding_quarter_window(df, window_size=2): # 分离ID列和季度数据列 id_col = df.iloc[:, [0]] quarter_data = df.iloc[:, 1:] # 每个季度对应2列(rev + transcnt) cols_per_qtr = 2 # 计算总季度数 total_qtrs = quarter_data.shape[1] // cols_per_qtr # 计算可生成的滑动窗口数量 window_count = total_qtrs - window_size + 1 result_list = [] for idx in range(window_count): # 截取当前窗口的季度数据列 start_col = idx * cols_per_qtr end_col = start_col + window_size * cols_per_qtr current_window = quarter_data.iloc[:, start_col:end_col] # 动态生成新列名 new_cols = [] for q in range(1, window_size + 1): new_cols.extend([f"{q}st_rev", f"{q}st_transcnt"]) current_window = current_window.set_axis(new_cols, axis=1) # 拼接ID列与当前窗口数据 result_list.append(pd.concat([id_col, current_window], axis=1)) # 合并所有窗口结果并重置索引 return pd.concat(result_list, ignore_index=True) # 测试用示例DataFrame df = pd.DataFrame({ 'ID': [100, 101], 'Q1_rev': [2, 3], 'Q1_transcnt': [200, 201], 'Q2_rev': [4, 5], 'Q2_transcnt': [300, 301], 'Q3_rev': [6, 7], 'Q3_transcnt': [400, 401], 'Q4_rev': [8, 9], 'Q4_transcnt': [500, 501] }) # 窗口大小为2时的输出(每个ID生成3行) output_window2 = sliding_quarter_window(df, window_size=2) print(output_window2) # 窗口大小为3时的输出(每个ID生成2行) output_window3 = sliding_quarter_window(df, window_size=3) print(output_window3)
关键特性
- 参数化窗口大小:通过
window_size参数可灵活设置每行包含的季度数量,比如设为4即可生成包含4个季度数据的行 - 自动计算窗口数量:根据输入DataFrame的季度列数自动计算可生成的滑动窗口数量,无需手动调整索引范围
- 动态列名:根据窗口大小自动生成对应的列名(如
1st_rev、2nd_transcnt等) - 保留ID关联:确保每一行窗口数据与原始ID一一对应
窗口大小为2时的预期输出
ID 1st_rev 1st_transcnt 2nd_rev 2nd_transcnt 0 100 2 200 4 300 1 101 3 201 5 301 2 100 4 300 6 400 3 101 5 301 7 401 4 100 6 400 8 500 5 101 7 401 9 501
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

