如何转置/透视按小时列存储的时间序列表格数据?
解决宽表转窄表(时间列拆分)的方法
你的需求本质是宽表转窄表(逆透视),把按小时拆分的列(T0-T23)转换成每行对应一个时间点的结构,以下是几种常用实现方式:
1. Excel/Power Query(无需编程)
适合日常办公场景,操作步骤:
- 选中源数据区域,点击「数据」选项卡 → 「从表格/范围」,导入Power Query编辑器
- 在编辑器中,选中
Day、Group、Signal这三列 - 点击「转换」选项卡 → 「逆透视列」→ 「逆透视其他列」
- 此时会生成
Attribute(原T0-T23列名)和Value(对应数值)两列,接下来处理时间格式:- 添加自定义列,公式:
Text.PadStart(Text.Replace([Attribute], "T", ""), 2, "0") & ":00" - 重命名列:将
Day改为Date,自定义列改为Time,Value改为SignalValue
- 添加自定义列,公式:
- 最后关闭并上载到Excel,即可得到目标格式
2. Python Pandas(编程实现)
适合批量处理大量数据,代码示例:
import pandas as pd # 读取源数据(可替换为读取csv/excel文件) df = pd.DataFrame({ "Day": ["2022-01-01", "2022-01-01"], "Group": ["Voltage", "Voltage"], "Signal": ["L1", "L2"], "T0": [230.0, 225.4], "T1": [229.5, 231.2], "T23": [231.2, 230.3] }) # 逆透视处理:保留固定列,将T0-T23转为行 melted_df = df.melt( id_vars=["Day", "Group", "Signal"], var_name="Hour", value_name="SignalValue" ) # 生成Time列:将T后数字转为HH:00格式 melted_df["Time"] = melted_df["Hour"].str.replace("T", "").str.zfill(2) + ":00" # 调整列名和顺序 result_df = melted_df.rename(columns={"Day": "Date"})[["Date", "Time", "Group", "Signal", "SignalValue"]] print(result_df)
3. SQL(数据库场景)
如果数据存储在数据库中,可使用以下两种方式实现:
方法1:UNPIVOT(适用于SQL Server、Oracle等支持该语法的数据库)
SELECT Day AS Date, CONCAT(RIGHT('0' + REPLACE(Attribute, 'T', ''), 2), ':00') AS Time, "Group", Signal, SignalValue FROM YourTableName UNPIVOT ( SignalValue FOR Attribute IN (T0, T1, T2, ..., T23) ) AS UnpivotTable;
方法2:UNION ALL(全数据库兼容)
SELECT Day AS Date, '00:00' AS Time, "Group", Signal, T0 AS SignalValue FROM YourTableName UNION ALL SELECT Day AS Date, '01:00' AS Time, "Group", Signal, T1 AS SignalValue FROM YourTableName UNION ALL -- 依次添加T2到T22的查询语句 UNION ALL SELECT Day AS Date, '23:00' AS Time, "Group", Signal, T23 AS SignalValue FROM YourTableName ORDER BY Date, Signal, Time;
内容的提问来源于stack exchange,提问作者Agent 47
相关产品推荐
相关产品推荐

