将pandas数据帧从wide转换为long

时间:2017-07-16 00:33:33

标签: python pandas

我有一个pandas.Dataframe,其中包含以下列:

a    ab    ac 
2     3     4
5     6     7 

如何将其转换为以下内容?

sizeHint()

我试图使用pandas melt来从宽格式转换为长格式,但不确定语法。

6 个答案:

答案 0 :(得分:5)

您可以使用多索引和堆栈替换列:

df.columns = pd.MultiIndex.from_tuples(df.columns.str.split('_').map(tuple))
df = df.stack()

答案 1 :(得分:3)

这是一种方法:

代码:

df.columns = pd.MultiIndex.from_tuples(
    [c.split('_') for c in df.columns], names=['col', 'row'])

df.melt().pivot(index='row', columns='col', values='value')

如何?

  1. 通过拆分_为列创建pandas.MultiIndex

  2. melt数据框,然后是pivot原始列名称中的元素。

  3. 测试代码:

    df = pd.DataFrame(
        data=[range(2, 8)],
        columns='a_1 ab_1 ac_1 a_2 ab_2 ac_2'.split()
    )
    print(df)
    
    df.columns = pd.MultiIndex.from_tuples(
        [c.split('_') for c in df.columns], names=['col', 'row'])
    
    print(df.melt().pivot(index='row', columns='col', values='value'))
    

    结果:

       a_1  ab_1  ac_1  a_2  ab_2  ac_2
    0    2     3     4    5     6     7
    
    col  a  ab  ac
    row           
    1    2   3   4
    2    5   6   7
    

    pandas< 0.20.0

    如果在0.20.0之前使用pandas,melt()喜欢:

    print(pd.melt(df).pivot(index='row', columns='col', values='value'))
    

答案 2 :(得分:2)

您可以MultiIndex使用split,然后按stack重新塑造,最后使用reset_index删除MultiIndex

df.columns = df.columns.str.split('_', expand=True)
df = df.stack().reset_index(drop=True)
print (df)
   a  ab  ac
0  2   3   4
1  5   6   7
df = df.stack().reset_index(level=0, drop=True)
print (df)
   a  ab  ac
1  2   3   4
2  5   6   7

答案 3 :(得分:1)

您可以将数据框拆分为两个,然后重命名列,最后将它们连接起来:

cols = ['a', 'ab', 'ac']
df1 = df[["a_1", "ab_1", "ac_1"]]
df2 = df[["a_2", "ab_2", "ac_2"]]
df1.columns = cols
df2.columns = cols
df3 = pd.concat([df1, df2], ignore_index=True)

答案 4 :(得分:1)

如果您想使用pnd.melt,您应该使用value_varsvalue_name参数:

df_a = pnd.melt(df, value_vars=['a_1', 'a_2'], value_name='a')[['a']]
df_ab = pnd.melt(df, value_vars=['ab_1', 'ab_2'], value_name='ab')[['ab']]
df_ac = pnd.melt(df, value_vars=['ac_1', 'ac_2'], value_name='ac')[['ac']]
df_final = df_a.join(df_b).join(df_c)

或者,采取更实用的方法:

col_prefixes = ['a', 'ab', 'ac']
df_cuts = map(lambda x: pnd.melt(df, value_vars=['%s_1' % x, '%s_2' % x], value_name=x)[[x]], col_prefixes)
df_final = reduce(lambda x, y: x.join(y), df_cuts)

答案 5 :(得分:1)

内置函数wide_to_long可以在文档中看到更多内容:

In [115]: df
Out[115]: 
   a_1  ab_1  ac_1  a_2  ab_2  ac_2
0    2     3     4    5     6     7

In [116]: df['id'] = df.index

In [117]: df
Out[117]: 
   a_1  ab_1  ac_1  a_2  ab_2  ac_2  id
0    2     3     4    5     6     7   0
In [118]: pd.wide_to_long(df, ['a','ab','ac'],i='id',j='num',sep='_')
Out[118]: 
        a  ab  ac
id num           
0  1    2   3   4
   2    5   6   7