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

时间:2019-06-28 12:37:58

标签: python python-3.x pandas dataframe melt

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

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]})

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

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

尽管这适用于如下所示的示例数据,但不适用于我的实际数据,该数据有200列以上。我的真实数据不是subject_id,而是我的真实数据,它的subject_ID是DC0001,DC0002等值。“ I”是否总是必须为数字?相反,它将存根值添加为数据集中的新列,并且行数为零

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

enter image description here

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

enter image description here

请问您能解决什么问题?或任何其他获得相同结果的方法也很有帮助。

2 个答案:

答案 0 :(得分:0)

问题出在您的列名上,用于从宽到长转换的数字必须在列名的末尾,或者您需要为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

答案 1 :(得分:0)

尝试在允许字符串后缀的函数中添加其他参数。

pd.long_to_wide(.......................,suffix='\w+')