pandas如何将ID非唯一的多列宽表重塑为单列长表
问题解决方法
你原来的pd.wide_to_long代码无法得到预期结果的核心原因是:该函数要求i参数传入的列组合可以唯一标识每一行,而你的df1中ID列全部重复,不满足这个要求。你不需要额外结合unstack操作,用更适配的pd.melt函数就能快速实现需求。
方法1:使用pd.melt实现(推荐,逻辑更简单)
import pandas as pd import numpy as np # 原始数据构造 df1 = pd.DataFrame({'ID':[110813,110813,110813,110813], 'DATE1':['2019-09-19','2020-05-20',np.nan,np.nan], 'DATE2':[np.nan,'2020-06-15',np.nan,'2019-10-24'], 'DATE3':[np.nan,'2020-07-20','2020-08-30',np.nan]}) # 转换逻辑 result = df1.melt( id_vars='ID', # 保留ID列不变 value_vars=['DATE1','DATE2','DATE3'], # 指定要转换的宽列 value_name='DATE' # 转换后的值列命名为DATE ).dropna(subset=['DATE']) # 删掉日期为空的无效行 .sort_values('DATE') # 按日期升序排序 .drop(columns='variable') # 删掉多余的列名标识列 .reset_index(drop=True) # 重置行索引
运行后得到的result就是你需要的目标表结构。
方法2:如果你坚持使用wide_to_long实现
只需要先新增一个行唯一标识列即可:
df1['row_seq'] = df1.index result = pd.wide_to_long( df1, stubnames='DATE', i=['ID','row_seq'], # 用ID+行序号组合作为唯一行标识 j='DATE_TYPE' ).dropna() .reset_index() .sort_values('DATE') [['ID','DATE']] .reset_index(drop=True)
两种方法得到的结果完全一致。
内容的提问来源于stack exchange,提问作者Mazil_tov998
相关产品推荐
相关产品推荐

