与熊猫交错的换位

时间:2015-08-04 19:51:40

标签: python numpy pandas

我有一个这样的数据表(忽略索引):

group, subgroup, score 
A, B, 0
A, C, 1.5
A, A, 5
B, A, 1
B, F, 1.5
B, C, 0
C, C, 2
C, D, 3

我想要一张这样的桌子:

group, subgroup w lowest score, w second lowest score, w third lowest
A, B, C, A
B, C, A, F
C, C, D, (blank) 

我如何使用Pandas从一个到另一个?

3 个答案:

答案 0 :(得分:2)

一种方法是引入一个对子组进行排名然后再进行调整的列。 首先按分数排序并按变换进行分组:

df.sort('score', inplace=True)
ranks = ['lowest', 'second lowest', 'third lowest']
df['rank'] = df.groupby('group').subgroup.transform(lambda s: ranks[:len(s)])

然后转动:

In [44]:    df.pivot(index='group', columns='rank', values='subgroup')

Out[44]:
rank    lowest  second lowest   third lowest
group           
A   B   C   A
B   C   A   F
C   C   D   NaN

答案 1 :(得分:2)

这是一种非常紧凑的方式。为了简单起见,我用排名写了“得分”值,但是如果你愿意的话,你可以保留原来的分数(这只是一点点冗长)。

df['score'] = df.groupby('group')['score'].rank()
df.set_index(['group','score']).unstack()

      subgroup        
score        1  2    3
group                 
A            B  C    A
B            C  A    F
C            C  D  NaN

请注意,这会阻塞第一个或第二个存在平局的数据。你可以通过各种方式解决这个问题(例如,rank(method='first')是单向的,但rank也为你提供了其他选项)。你没有指定,所以我不确定你想怎么处理它。

编辑添加:现在我正在更仔细地查看@ JoeCondron的答案我发现我的方法非常相似,但我认为它们的不同之处我会留下一点点至少。特别是乔正在排序,我的排名在你如何处理平局时可能很重要。

答案 2 :(得分:1)

由于可能存在没有“第三低分”的情况,我们可能需要itertools.izip_longest

In [85]:

from itertools import izip_longest
gby = df.groupby(['group']).agg(lambda x: tuple(x))
print pd.DataFrame(data = list(izip_longest(*map(lambda x, y: [v[1] for v in sorted(zip(y,x))], 
                                                 gby.subgroup, gby.score))),
                   columns= gby.index,
                   index = ['subgroup w lowest score', 
                            'w second lowest score', 
                            'w third lowest']).T 


      subgroup w lowest score w second lowest score w third lowest
group                                                             
A                           B                     C              A
B                           C                     A              F
C                           C                     D           None