按名称将列组熔合到目标列中

时间:2018-04-30 15:23:55

标签: python pandas dataframe transform

此问题建立在Pandas melt several groups of columns into multiple target columns by name之上。但是,我的数据是以一种正确的方式组织的

import pandas as pd

df = pd.DataFrame([(101, 'a', 'b', 'c', 'd', 'e', 'f', 1, 2, 3, 4, 5, 6, 'aa', 'bb', 'cc', 'dd', 'ee', 'ff'),
                   (102,'g', 'h', 'i', 'j', 'k', 'l' , 7, 8, 9, 10, 11, 12, 'gg', 'hh', 'ii', 'jj', 'kk', 'll')], 
                   columns=['id','a__1', 'a__2', 'a__3', 'a_1', 'a_2', 'a_3','b__1', 'b__2', 'b__3', 'b_1', 'b_2', 'b_3','c__1', 'c__2', 'c__3', 'c_1', 'c_2', 'c_3'])

df

数据框看起来像这样:

    id a__1 a__2 a__3 a_1 a_2 a_3  b__1  b__2  b__3  b_1  b_2  b_3 c__1 c__2  \
0  101    a    b    c   d   e   f     1     2     3    4    5    6   aa   bb   
1  102    g    h    i   j   k   l     7     8     9   10   11   12   gg   hh   

  c__3 c_1 c_2 c_3  
0   cc  dd  ee  ff  
1   ii  jj  kk  ll 

正如你所看到的,而不是所有的分隔符只是一个下划线,它们有时是两个下划线。

最后,我想以下列方式组织我的数据,请注意a__1应该在a_1之前,依此类推:

     id   a   b   c
0   101   a   1   aa
1   101   b   2   bb
2   101   c   3   cc
3   101   d   4   dd
4   101   e   5   ee
5   101   f   6   ff   
6   102   g   7   gg
7   102   h   8   hh
8   102   i   9   ii
9   102   j   10  jj
10  102   k   11  kk
11  102   l   12  ll

基本上我的问题是,我有时只有一个下划线而不是2.现在这不适用于pd.wide_to_long函数,因为我不能将separator参数设置为'_'或'__'。我希望你理解我的问题。

2 个答案:

答案 0 :(得分:2)

你可以使用repalce reaplce all'_'和'__'to'',然后我们使用stack来重塑你的df,使用cumcount后创建唯一键我们可以实现你的目标需要

df.columns=df.columns.str.replace('_','')
s=df.set_index('id').stack().reset_index(level=1)
s.level_1=s.level_1.str[0]
s['New']=s.groupby('level_1').cumcount()



s.set_index(['New','level_1'],append=True)[0].unstack()


Out[509]: 
level_1  a   b   c
id  New           
101 0    a   1  aa
    1    b   2  bb
    2    c   3  cc
    3    d   4  dd
    4    e   5  ee
    5    f   6  ff
102 6    g   7  gg
    7    h   8  hh
    8    i   9  ii
    9    j  10  jj
    10   k  11  kk
    11   l  12  ll

答案 1 :(得分:2)

您可以使用@Wen旧收藏夹pd.wide_to_long

pd.wide_to_long(df,['a','b','c'],i='id',j='new',sep='_',suffix='.')\
  .reset_index('new', drop=True)\
  .sort_index()

输出:

     a   b   c
id            
101  a   1  aa
101  b   2  bb
101  c   3  cc
101  d   4  dd
101  e   5  ee
101  f   6  ff
102  g   7  gg
102  h   8  hh
102  i   9  ii
102  j  10  jj
102  k  11  kk
102  l  12  ll