如何将长格式时间序列数据重塑为含StartTime/StopTime的宽格式
将长格式时间序列数据转换为带时间区间的宽格式
我需要把长格式的时间序列数据重塑为宽格式,要求包含StartTime(对应示例中的From)和StopTime(对应示例中的To)列,同一时间区间内的所有变量需放在同一行。
原始数据集
Id Time Status Col1 10 2012 4 2 11 2009 2 5 11 2010 2 5 12 2004 2 2 12 2009 2 3 12 2011 2 1 12 2018 2 3 17 2018 2 3 17 2020 2 1
期望输出数据集
Id From To Status Col1 10 2012 2012 4 2 11 2009 2010 2 5 12 2004 2009 2 2 12 2009 2011 2 3 12 2011 2018 2 1 12 2018 2018 2 3 17 2018 2020 2 3 17 2020 2020 2 1
解决方案
方法1:R语言(dplyr + tidyr)
按Id分组后,将当前行的Time设为区间起始,下一行的Time设为区间结束;最后一行的结束时间与起始时间保持一致:
library(dplyr) # 先确保数据按Id和Time排序(如果原始数据未排序) df <- df %>% arrange(Id, Time) df %>% group_by(Id) %>% mutate( From = Time, To = lead(Time, default = last(Time)) ) %>% ungroup() %>% select(Id, From, To, Status, Col1)
方法2:Python(Pandas)
按Id分组,用shift获取下一行的时间作为区间结束,最后一行用自身时间填充结束值:
import pandas as pd # 先确保数据按Id和Time排序(如果原始数据未排序) df = df.sort_values(['Id', 'Time']) df['To'] = df.groupby('Id')['Time'].shift(-1) df['To'] = df['To'].fillna(df['Time']) df = df.rename(columns={'Time': 'From'}) df = df[['Id', 'From', 'To', 'Status', 'Col1']]
关键说明
- 两种方法都依赖同一Id内的时间顺序生成区间,若原始数据未按
Id和Time排序,必须先执行排序操作。 - 逻辑规则:当前记录的时间为区间起点,下一条记录的时间为区间终点;该Id的最后一条记录,终点与起点相同。
内容的提问来源于stack exchange,提问作者Ahir Bhairav Orai
相关产品推荐
相关产品推荐

