2015-11-09 18 views
1

我有这样的事情:熊猫据帧 - 变换列值成单独列

XY UV BC Val 
0 y u c 11 
1 y u b 22 
2 y v c 33 
3 y v b 44 
4 x u c 111 
5 x u b 222 
6 x v c 333 
7 x v b 444 

我想获得

XY UV B_Val C_Val 
0 y u 22  11 
1 y v 44  33 
2 x u 222 111 
3 x v 444  333 

一般来说,BC上面列可以包含若干不同的项目,所以我需要一个适用于一般情况的解决方案,不仅适用于2个不同的值。

我试着写了一些拆分数据帧的代码,而不是重新加入单独的部分,但它开始看起来太复杂了,而且它不会去任何地方。

回答

2

这里我喜欢使用多级索引和堆栈/叠加。

所以在这里,我会做:

from io import StringIO 
import pandas 

datacsv = StringIO("""\ 
XY UV BC Val 
y u c 11 
y u b 22 
y v c 33 
y v b 44 
x u c 111 
x u b 222 
x v c 333 
x v b 444 
""") 
df = pandas.read_csv(datacsv, sep='\s+') 
df.set_index(['XY', 'UV', 'BC']).unstack(level='BC') 

这给了我们:

 Val  
BC  b c 
XY UV   
x u 222 111 
    v 444 333 
y u 22 11 
    v 44 33 

因此,我们必须对行和列都MultiIndexes。假设你不希望这样,我只想做:

xtab = (df.set_index(['XY', 'UV', 'BC']) 
      .unstack(level='BC')['Val'] 
      .reset_index()) 

这会给你:

BC XY UV b c 
0 x u 222 111 
1 x v 444 333 
2 y u 22 11 
3 y v 44 33 
+0

如何将列索引从'BC'重命名为'index'? –

+0

这实际上是列索引级别的名称。尝试'xtab.columns.names = []'或者它可能是'xtab.columns.index.names = []' –

+0

我得到了ValueError:新名称的长度必须是1,得到0 –

2

IIUC要pivot

In [110]: 
df.pivot(index='XY',columns='BC', values='Val') 

Out[110]: 
BC b c 
XY   
x 10 20 
y 33 44 

编辑

pivot不支持多指数DF的这是一个方法,我正在考虑,你可以做的是增加一个新列它是2列的组合并且用它作为pivot的索引:

In [120]: 
df['composite'] = df['XY']+df['UV'] 
df 

Out[120]: 
    XY UV BC Val composite 
0 y u c 11  yu 
1 y u b 22  yu 
2 y v c 33  yv 
3 y v b 44  yv 
4 x u c 111  xu 
5 x u b 222  xu 
6 x v c 333  xv 
7 x v b 444  xv 

In [121]: 
df.pivot(index='composite', columns='BC', values='Val') 

Out[121]: 
BC   b c 
composite   
xu   222 111 
xv   444 333 
yu   22 11 
yv   44 33 
+0

如何进行指数=子句的样子,如果我有超过1列类似于XY?我很抱歉添加了这样的问题。 –

+0

我真的不明白你在问什么,就像我之前说过的,除非你发表一个有代表性的数据和期望的输出的问题,那么很难回答投机性的问题 – EdChum

+0

请看看我的改进的例子。谢谢 –

1

你也可以使用这样的多索引和垛:

df=df.set_index(['XY','UV','BC']) 
df=df.unstack('BC')