如何在Pandas中实现数据帧列转行?附具体转换需求示例
搞定Pandas宽表转长表的需求
嘿,这个转换其实很简单,Pandas有专门的工具来处理这种宽表转长表的场景,我给你两种实用的方法:
首先先把你的示例数据用代码还原出来,方便咱们测试:
import pandas as pd # 构造原始数据帧 df = pd.DataFrame({ 'code': [123, 123, 123], 'date': ['2019-01-01', '2019-01-01', '2019-01-01'], 'tank': [1, 2, 3], 'product': ['MS', 'HS', 'MS'], 'time_frst': ['02:00:00', '02:30:00', '00:30:00'], 'time_lst': ['10:00:00', '19:00:00', '22:00:00'], 'qty_frst': [234, 200, 300], 'qty_lst': [100, 50, 500] })
方法一:用melt()批量转换(推荐,适合列名有规律的场景)
melt()是Pandas专门用于宽表转长表的函数,能一次性匹配对应的时间和数量列:
# 核心转换代码 df_transformed = df.melt( # 指定不需要转换的固定列 id_vars=['code', 'date', 'tank', 'product'], # 传入对应的列对:(时间列, 数量列) value_vars=[('time_frst', 'qty_frst'), ('time_lst', 'qty_lst')], # 临时列名(后续会删掉) var_name=['_time_type', '_qty_type'], # 目标列名 value_name=['time', 'qty'] ).drop(['_time_type', '_qty_type'], axis=1) # 重置索引让结果更整齐 df_transformed = df_transformed.reset_index(drop=True)
方法二:拆分后拼接(逻辑更直观,新手友好)
如果觉得melt有点绕,也可以把两次的记录分别提取出来,重命名列后拼接:
# 提取第一次的时间和数量数据,并重命名列 df_first = df[['code', 'date', 'tank', 'product', 'time_frst', 'qty_frst']].rename( columns={'time_frst': 'time', 'qty_frst': 'qty'} ) # 提取第二次的时间和数量数据,并重命名列 df_last = df[['code', 'date', 'tank', 'product', 'time_lst', 'qty_lst']].rename( columns={'time_lst': 'time', 'qty_lst': 'qty'} ) # 拼接两个数据帧,忽略原索引 df_transformed = pd.concat([df_first, df_last], ignore_index=True) # 可选:按code、date、tank排序,让结果和你的示例顺序完全一致 df_transformed = df_transformed.sort_values(by=['code', 'date', 'tank']).reset_index(drop=True)
运行任意一种方法后,你就能得到和期望完全一致的数据帧啦!两种方法都能达到目的,如果你有更多类似的列对要转换,优先选方法一;如果逻辑想更清晰,方法二更合适。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

