如何在Python中将多房间列结构CSV转换为堆叠列结构?
解决方案
针对你的宽表转长表需求,这里提供两种可靠的处理方式,适配房间数量动态变化的场景:
方法1:按列名的数字后缀匹配(推荐,若列名严格遵循room N/temperature N/humidity N格式)
这种方式依赖列名的数字标识来关联同一房间的三个指标,无需依赖列的顺序:
import pandas as pd # 读取CSV并清理列名(处理原始列名的前后空格) df = pd.read_csv('your_data.csv') df.columns = df.columns.str.strip() # 1. 拆分非Date列的指标类型与房间编号 melted = df.melt(id_vars=['Date'], var_name='metric', value_name='value') melted[['metric_type', 'room_id']] = melted['metric'].str.split(n=1, expand=True) # 2. 将指标类型转成列,实现宽转长 result = melted.pivot_table( index=['Date', 'room_id'], columns='metric_type', values='value', aggfunc='first' ).reset_index() # 3. 重命名列以符合需求 result = result.rename(columns={ 'room': 'Room', 'temperature': 'Temperature', 'humidity': 'Humidity' }) # 可选:过滤掉无房间名称的行(适配中途新增房间的NaN数据) result = result.dropna(subset=['Room'])
方法2:按列顺序分组(适配列名无统一数字标识,但严格按room → temperature → humidity顺序排列的场景)
如果列名的数字标识不严谨,但每三个列严格对应一个房间的名称、温度、湿度,用这种方式更稳妥:
import pandas as pd df = pd.read_csv('your_data.csv') df.columns = df.columns.str.strip() result_rows = [] # 遍历每一行数据 for _, row in df.iterrows(): current_date = row['Date'] # 提取除Date外的所有列 non_date_cols = [col for col in df.columns if col != 'Date'] # 每3个列分为一组(房间名称、温度、湿度) for i in range(0, len(non_date_cols), 3): room_name = row[non_date_cols[i]] # 跳过无房间名称的行(对应中途新增的空房间数据) if pd.isna(room_name): continue temp = row[non_date_cols[i+1]] hum = row[non_date_cols[i+2]] result_rows.append({ 'Date': current_date, 'Room': room_name, 'Temperature': temp, 'Humidity': hum }) # 转换为最终DataFrame result_df = pd.DataFrame(result_rows)
目标表格式优化建议
- 新增Room_ID列:保留原始的房间编号(如1、2、3),方便追溯原始数据的分组关系,同时用Room列存储实际房间名称(如卧室、客厅);
- 统一Date类型:将Date列转换为
datetime类型,便于后续时间序列分析、按时间筛选等操作; - 处理缺失值:针对中途新增房间产生的NaN数据,可选择过滤或标记为“未记录”,避免无效数据干扰;
- 原始CSV列名优化:建议将原始列名改为更清晰的格式,如
Room_1_Name、Room_1_Temperature、Room_1_Humidity,降低程序识别的出错概率。
内容的提问来源于stack exchange,提问作者lygho
相关产品推荐
相关产品推荐

