Unmelt Pandas DataFrame

sla*_*law 18 python pandas

我有一个带有两个id变量的pandas数据帧:

df = pd.DataFrame({'id': [1,1,1,2,2,3], 
               'num': [10,10,12,13,14,15],
               'q': ['a', 'b', 'd', 'a', 'b', 'z'],
               'v': [2,4,6,8,10,12]})

   id  num  q   v
0   1   10  a   2
1   1   10  b   4
2   1   12  d   6
3   2   13  a   8
4   2   14  b  10
5   3   15  z  12
Run Code Online (Sandbox Code Playgroud)

我可以用以下方式转动表:

df.pivot('id','q','v')
Run Code Online (Sandbox Code Playgroud)

并最终结束了一些事情:

q    a   b   d   z
id                
1    2   4   6 NaN
2    8  10 NaN NaN
3  NaN NaN NaN  12
Run Code Online (Sandbox Code Playgroud)

但是,我真正想要的是(原始的未融合形式):

id   num   a   b   d   z               
1    10   2   4 NaN NaN
1    12 NaN NaN   6 NaN  
2    13   8 NaN NaN NaN
2    14 NaN  10 NaN NaN
3    15 NaN NaN NaN  12
Run Code Online (Sandbox Code Playgroud)

换一种说法:

  1. 'id'和'num'我的索引(通常,我只看到'id'或'num'作为索引,但我需要两个,因为我正在尝试检索原始未融合的表单)
  2. 'q'是我的专栏
  3. 'v'是我在桌子上的价值观

更新

我从Wes McKinney的博客中找到了一个密切的解决方案:

df.pivot_table(index=['id','num'], columns='q')

         v            
q        a   b   d   z
id num                
1  10    2   4 NaN NaN
   12  NaN NaN   6 NaN
2  13    8 NaN NaN NaN
   14  NaN  10 NaN NaN
3  15  NaN NaN NaN  12
Run Code Online (Sandbox Code Playgroud)

但是,格式与上面我想要的格式不完全相同.

kha*_*mel 17

你真的很亲密.只需将列索引重命名为None,即可获得所需内容.

df2 = df.pivot_table(index=['id','num'], columns='q')
df2.columns = df2.columns.droplevel().rename(None)
df2.reset_index().fillna("null").to_csv("test.csv", sep="\t", index=None)
Run Code Online (Sandbox Code Playgroud)

请注意,默认情况下,'v'列应为数字,以便可以聚合.否则,熊猫会出错:

DataError: No numeric types to aggregate
Run Code Online (Sandbox Code Playgroud)

要解决此问题,您可以使用自定义lambda函数指定自己的聚合函数:

df2 = df.pivot_table(index=['id','num'], columns='q', aggfunc= lambda x: x)
Run Code Online (Sandbox Code Playgroud)

  • 重要提示:"close slaw"听起来像"凉拌卷心菜". (5认同)

Zer*_*ero 14

你可以使用set_indexunstack

In [18]: df.set_index(['id', 'num', 'q'])['v'].unstack().reset_index()
Out[18]:
q  id  num    a     b    d     z
0   1   10  2.0   4.0  NaN   NaN
1   1   12  NaN   NaN  6.0   NaN
2   2   13  8.0   NaN  NaN   NaN
3   2   14  NaN  10.0  NaN   NaN
4   3   15  NaN   NaN  NaN  12.0
Run Code Online (Sandbox Code Playgroud)

  • 这比接受的答案要干净得多。谢谢! (2认同)