使用pandas将宽表转长表:后缀非末尾的处理建议
处理非末尾后缀的宽表转长格式方案
针对你的需求,由于_V0/_V1后缀并非固定在列名末尾,直接使用pd.wide_to_long会因为匹配不到正确的stubnames而失败,这里提供两种高效的处理方案,尤其适合大规模数据集:
方案一:重命名列统一后缀位置(推荐,效率更高)
核心思路是先将所有列中的_V0/_V1后缀移动到列名末尾,让列名符合pd.wide_to_long的预期格式,再进行转换:
步骤1:重命名列,将_V0/_V1移至末尾
使用正则表达式替换,把任意位置的_V0/_V1调整到列名最后:
import pandas as pd # 示例数据集(实际需替换为你的数据) df = pd.DataFrame({ 'ID': [1, 2, 3], 'ONOFF_LEVER_V0': [0, 1, 0], 'ONOFF_LEVER_V1': [1, 1, 0], 'LEDD_DOPA_V0_categ_1': ['low', 'medium', 'high'], 'LEDD_DOPA_V1_categ_1': ['medium', 'high', 'low'] }) # 仅重命名包含_V0/_V1的列 rename_map = { col: col.replace(r'(.*)(_V[01])(.*)', r'\1\3\2', regex=True) for col in df.columns if '_V0' in col or '_V1' in col } df = df.rename(columns=rename_map)
重命名后,列名会变成:ID, ONOFF_LEVER_V0, ONOFF_LEVER_V1, LEDD_DOPA_categ_1_V0, LEDD_DOPA_categ_1_V1,所有_V0/_V1都在末尾。
步骤2:使用pd.wide_to_long转换
指定stubnames为目标变量名,处理visit列的转换:
# 宽转长,i为你的标识符列(比如ID) long_df = pd.wide_to_long( df, stubnames=['ONOFF_LEVER', 'LEDD_DOPA_categ_1'], i='ID', j='visit', suffix='V[01]' ).reset_index() # 将visit的V0/V1转为0/1 long_df['visit'] = long_df['visit'].str.replace('V', '').astype(int)
方案二:使用melt+字符串拆分(无需重命名)
如果不想修改列名,可以先将宽表熔化为长表,再拆分变量名提取visit和目标字段:
# 第一步:熔化为长表 melted = df.melt(id_vars=['ID'], var_name='raw_var', value_name='value') # 第二步:拆分raw_var列,提取变量名和visit # 正则匹配任意位置的_V0/_V1,拆分出变量名主体和visit标识 melted[['prefix', 'visit', 'suffix']] = melted['raw_var'].str.extract(r'(.*?)_V([01])(.*)') melted['var_name'] = melted['prefix'] + melted['suffix'] melted['visit'] = melted['visit'].astype(int) # 第三步:转回宽表得到目标格式 long_df = melted.pivot_table( index=['ID', 'visit'], columns='var_name', values='value', aggfunc='first' ).reset_index() long_df.columns.name = None # 清除列名的层级名称
注意事项
- 确保数据集有唯一标识符列(如示例中的
ID),否则转长后无法对应原始行数据。 - 若存在不包含
_V0/_V1的列,需将其纳入id_vars参数中保留。
内容的提问来源于stack exchange,提问作者user1363251
相关产品推荐
相关产品推荐

