从宽到长返回空输出 - Python 数据框

SSM*_*SMK 5 python dataframe melt python-3.x pandas

我有一个数据框,可以从下面给出的代码生成

df = pd.DataFrame({'person_id' :[1,2,3],'date1': 
['12/31/2007','11/25/2009','10/06/2005'],'val1': 
[2,4,6],'date2': ['12/31/2017','11/25/2019','10/06/2015'],'val2':[1,3,5],'date3': 
['12/31/2027','11/25/2029','10/06/2025'],'val3':[7,9,11]})
Run Code Online (Sandbox Code Playgroud)

我按照下面的解决方案将其从宽转换为长

pd.wide_to_long(df, stubnames=['date', 'val'], i='person_id', 
j='grp').sort_index(level=0)
Run Code Online (Sandbox Code Playgroud)

虽然这适用于如下所示的示例数据,但它不适用于我的超过 200 列的真实数据。我的真实数据不是 person_id,而是 subject_ID,它是 DC0001、DC0002 等值。“I”总是必须是数字吗?相反,它将存根值添加为我的数据集中的新列,并且行数为零

这就是我真正的专栏的样子

在此输入图像描述

我的真实数据可能也包含 NA。那么我是否必须用 Wide_to_long 的默认值填充它们才能工作?

在此输入图像描述

您能帮忙看看可能是什么问题吗?或者任何其他达到相同结果的方法也是有帮助的。

HS-*_*ula 2

问题在于您的列名称,用于从宽转换为长的数字需要位于列名称的末尾,或者您需要指定 groupby 的后缀。我认为最简单的解决方案是创建一个接受正则表达式和数据帧的函数。

import pandas as pd
import re

def change_names(df, regex):
    # Select one of three column groups
    old_cols = df.filter(regex = regex).columns
    # Create list of new column names
    new_cols = []
    for col in old_cols:
        # Get the stubname of the original column
        stub = ''.join(re.split(r'\d', col))
        # Get the time point
        num = re.findall(r'\d+', col) # returns a list like ['1']
        # Make new column name
        new_col = stub + num[0]
        new_cols.append(new_col)

    # Create dictionary mapping old column names to new column names
    dd = {oc: nc for oc, nc in zip(old_cols, new_cols)}
    # Rename columns
    df.rename(columns = dd, inplace = True)

    return df


tdf = pd.DataFrame({'person_id' :[1,2,3],'h1date': ['12/31/2007','11/25/2009','10/06/2005'],'t1val': [2,4,6],'h2date': ['12/31/2017','11/25/2019','10/06/2015'],'t2val':[1,3,5],'h3date': ['12/31/2027','11/25/2029','10/06/2025'],'t3val':[7,9,11]})

# Change date columns
tdf = change_names(tdf, 'date$')
tdf = change_names(tdf, 'val$')

print(tdf)
    person_id      hdate1  tval1      hdate2  tval2      hdate3  tval3
0          1  12/31/2007      2  12/31/2017      1  12/31/2027      7
1          2  11/25/2009      4  11/25/2019      3  11/25/2029      9
2          3  10/06/2005      6  10/06/2015      5  10/06/2025     11
Run Code Online (Sandbox Code Playgroud)