转换长数据帧并提取字符串

时间:2020-04-08 15:16:37

标签: python pandas dataframe

嗨,我有这样的数据框:

    Date A_2002 B_2003 C_2004 D_2005 Type
03-2002   20     30      12     42    X
04-2002   12     321     12     23    X
03-2002   10     31      2      3     Y

我想将其转换为长版本并从中提取字符串类型,因此最终结果将是这样:

   Date NewCol Extracted Type Value
03-2002 A       2002      X    20
03-2002 B       2003      X    30
03-2002 C       2004      X    12
03-2002 D       2005      X    42
04-2002 A       2002      X    12
04-2002 B       2003      X    321
04-2002 C       2004      X    12
04-2002 D       2005      X    23
03-2002 A       2002      Y    10
03-2002 B       2003      Y    31
03-2002 C       2004      Y    2
03-2002 D       2005      Y    3

因此,最终结果将把列名中的值转换为两个新值并融化数据,如上所示。熊猫有可能吗?

3 个答案:

答案 0 :(得分:5)

您可以在stackset_index之后执行str.split

m = df.set_index(['Date','Type'])
m.columns = m.columns.str.split('_',expand=True)
out = (m.stack([0,1]).rename('Value').reset_index()
     .rename(columns={'level_2':'NewCol','level_3':'Extracted'}))

       Date Type NewCol Extracted  Value
0   03-2002    X      A      2002   20.0
1   03-2002    X      B      2003   30.0
2   03-2002    X      C      2004   12.0
3   03-2002    X      D      2005   42.0
4   04-2002    X      A      2002   12.0
5   04-2002    X      B      2003  321.0
6   04-2002    X      C      2004   12.0
7   04-2002    X      D      2005   23.0
8   03-2002    Y      A      2002   10.0
9   03-2002    Y      B      2003   31.0
10  03-2002    Y      C      2004    2.0
11  03-2002    Y      D      2005    3.0

答案 1 :(得分:4)

我们可以在这里使用meltstr.split

out = df.melt(id_vars=['Date', 'Type'])

(out.assign(**out.pop('variable')
                 .str.split('_', expand=True)
                 .rename(columns=dict(zip(range(2), ['NewCol', 'Extracted'])))))

       Date Type  value NewCol Extracted
0   03-2002    X     20      A      2002
1   04-2002    X     12      A      2002
2   03-2002    Y     10      A      2002
3   03-2002    X     30      B      2003
4   04-2002    X    321      B      2003
5   03-2002    Y     31      B      2003
6   03-2002    X     12      C      2004
7   04-2002    X     12      C      2004
8   03-2002    Y      2      C      2004
9   03-2002    X     42      D      2005
10  04-2002    X     23      D      2005
11  03-2002    Y      3      D      2005

答案 2 :(得分:2)

这是使用pd.wide_to_long的一种方法。不错的事情是,尽管我们需要手动指定存根并且'Extracted'会浮动,但是wide_to_long将int64列转换为value

df = (pd.wide_to_long(df, i=['Date', 'Type'], j='Extracted',
                      stubnames=list('ABCD'), sep='_')
        .rename_axis('NewCol', axis=1)
        .stack()
        .rename('value')
        .reset_index())
#       Date Type  Extracted NewCol  value
#0   03-2002    X       2002      A   20.0
#1   03-2002    X       2003      B   30.0
#2   03-2002    X       2004      C   12.0
#3   03-2002    X       2005      D   42.0
#4   04-2002    X       2002      A   12.0
#5   04-2002    X       2003      B  321.0
#6   04-2002    X       2004      C   12.0
#7   04-2002    X       2005      D   23.0
#8   03-2002    Y       2002      A   10.0
#9   03-2002    Y       2003      B   31.0
#10  03-2002    Y       2004      C    2.0
#11  03-2002    Y       2005      D    3.0

df.dtypes
#Date          object
#Type          object
#Extracted      int64
#NewCol        object
#value        float64