如何对熊猫数据框中的一列进行分组,然后对另一列进行sort_values排序?

时间:2018-11-06 18:00:35

标签: python pandas

我有一个熊猫数据框,看起来像:

  SampleID      expr             Gene  Period                     tag
4   HSB103  7.214731  ENSG00000198615       5  HSB103|ENSG00000198615
2   HSB103  4.214731  ENSG00000198725       4  HSB103|ENSG00000198725
5   HSB100  3.214731  ENSG00000198615       4  HSB100|ENSG00000198615
1   HSB106  2.200031  ENSG00000198780       5  HSB106|ENSG00000198780
0   HSB103  1.214731  ENSG00000198780       4  HSB103|ENSG00000198780
3   HSB103  0.214731  ENSG00000198615       4  HSB103|ENSG00000198615

我想做的是按Gene分组,然后按降序expr排序,这样看起来像:

  SampleID      expr             Gene  Period                     tag
0   HSB103  7.214731  ENSG00000198615       5  HSB103|ENSG00000198615
1   HSB100  3.214731  ENSG00000198615       4  HSB100|ENSG00000198615
2   HSB103  0.214731  ENSG00000198615       4  HSB103|ENSG00000198615
3   HSB103  4.214731  ENSG00000198725       4  HSB103|ENSG00000198725
4   HSB106  2.200031  ENSG00000198780       5  HSB106|ENSG00000198780
5   HSB103  1.214731  ENSG00000198780       4  HSB103|ENSG00000198780

我尝试了以下方法,但是它们都不起作用:

尝试1:

p4p5.sort_values(by=['expr'], ascending=[False], inplace=True).groupby(['Gene'])

尝试2:

p4p5.groupby(['Gene'])
p4p5.sort_values(by=['expr'], ascending=[False], inplace=True)

更新为问题

一旦我进行了分组和排序,我该如何过滤数据框,以使每个基因组的表达只保留最底层的10%?当我说bottom 10%时,我的意思是从理论分布上讲,不是每个基因有100行,而是经过过滤后得到10行。我想那会是这样的:

p4p5.sort_values(by=['Gene','expr'], ascending=[True,False], inplace=True).quantile([0.1])

2 个答案:

答案 0 :(得分:4)

您在这里不需要groupby,只需在两列中使用sort_values,例如:

p4p5.sort_values(by=['Gene','expr'], ascending=[True,False], inplace=True)

编辑:对于更新的问题,可以使用groupbytail,例如:

p4p5_bottom10 = (p4p5.sort_values(by='expr', ascending=False).groupby('Gene')
                     .apply(lambda df_g: df_g.tail(int(len(df_g)*0.1))))

您也可以在末尾添加.reset_index(drop=True)

第二次编辑:希望这次我理解得很好,您可以这样做:

#first sort 
p4p5= p4p5.sort_values(['Gene','expr'], ascending=[True,False]).reset_index(drop=True)
# select the part of the data under quantile 10% (reset_index not mandatory)
p4p5_bottom10  = (p4p5[p4p5.groupby('Gene')['expr'].apply(lambda x: x < x.quantile(0.1))]
                       .reset_index(drop=True))

答案 1 :(得分:0)

简单的解决方案是:

>>> df.sort_values(['Gene','expr'],ascending=[True,False]).groupby('Gene').tail(3)
  SampleID      expr             Gene  Period                     tag
0   HSB103  7.214731  ENSG00000198615       5  HSB103|ENSG00000198615
2   HSB100  3.214731  ENSG00000198615       4  HSB100|ENSG00000198615
5   HSB103  1.214731  ENSG00000198615       4  HSB103|ENSG00000198615
1   HSB103  4.214731  ENSG00000198725       4  HSB103|ENSG00000198725
3   HSB106  2.200031  ENSG00000198780       5  HSB106|ENSG00000198780
4   HSB103  1.214731  ENSG00000198780       4  HSB103|ENSG00000198780