如何使用Python(pandas)按列中的出现次数对数据框进行排序

4

我正在尝试使用Python中的pandas从我的数据(化学物质和蛋白质之间的分数)创建数据帧。

我希望我的数据帧首先显示出现最多的蛋白质,所以我之前对我的数据进行了排序。但是当我创建数据帧时,它没有得到预期的结果。

这是我的数据样本:

chemicals   prots   scores
CID000000006    10116.ENSRNOP00000003921    196
CID000000051    10116.ENSRNOP00000003921    246
CID000000085    10116.ENSRNOP00000003921    196
CID000000119    10116.ENSRNOP00000003921    247
CID000000134    10116.ENSRNOP00000008952    159
CID000000135    10116.ENSRNOP00000008952    157
CID000000174    10116.ENSRNOP00000008952    439
CID000000175    10116.ENSRNOP00000001021    858
CID000000177    10116.ENSRNOP00000004027    760

您可以看到,“10116.ENSRNOP00000003921”是我数据中出现最多的蛋白质。

因此,我希望能够得到类似于:

             10116.ENSRNOP00000003921     10116.ENSRNOP00000008952  
CID000000006   196                 
CID000000051   246 
CID000000085   196 
CID000000119   247 
CID000000134                                  159   
CID000000135                                  157   
CID000000174                                  439

以下是我的代码:

import pandas as pd

df_rat= pd.read_csv("dt_matrix_rat.csv",sep="\t", header=True)
df_rat.columns = ['chemicals','proteins','scores']
df_rat1 = df_rat.pivot(index='chemicals', columns='proteins', values='scores')

df_rat1.to_csv("rat_matrix.csv", sep='\t', index=True  )

你可以使用 collections.Counter.most_common() 来获取出现次数,但是看起来你已经有了这些... 剩下的部分有点像数据透视表:https://en.wikipedia.org/wiki/Pivot_table - Swier
数据已经按蛋白质出现次数排序,只是我得到的矩阵没有以正确的顺序显示结果。 - user5103234
@ELWalou,您是指列的顺序错误还是行的顺序错误? - MaxU - stand with Ukraine
我不太明白你的问题,让我澄清一下。我认为你想创建一个新的数据框,其中列代表蛋白质,并按出现次数降序排序,而不是进行排序。我说得对吗? - jtitusj
@John,Titus确切地说,如果不太清楚,对不起。我会编辑我的帖子,努力让它更易理解。 - user5103234
2个回答

0

你可以使用@jezrael的解决方案,或者采用这种方式(非常相似):

In [136]: df
Out[136]:
      chemicals                     prots  scores
0  CID000000006  10116.ENSRNOP00000003921     196
1  CID000000051  10116.ENSRNOP00000003921     246
2  CID000000085  10116.ENSRNOP00000003921     196
3  CID000000119  10116.ENSRNOP00000003921     247
4  CID000000134  10116.ENSRNOP00000008952     159
5  CID000000135  10116.ENSRNOP00000008952     157
6  CID000000174  10116.ENSRNOP00000008952     439
7  CID000000175  10116.ENSRNOP00000001021     858
8  CID000000177  10116.ENSRNOP00000004027     760

准备正确的顺序
In [169]: df.groupby('prots').sum().sort('scores', ascending=False)
Out[169]:
                          scores
prots
10116.ENSRNOP00000003921     885
10116.ENSRNOP00000001021     858
10116.ENSRNOP00000004027     760
10116.ENSRNOP00000008952     755

准备排序列的列表(适用于旧版本的pandas),使用.sort()代替.sort_values()

In [170]: cols = df.groupby('prots').sum().sort_values(by='scores', ascending=False).index

In [171]: cols
Out[171]:
Index(['10116.ENSRNOP00000003921', '10116.ENSRNOP00000001021',
       '10116.ENSRNOP00000004027', '10116.ENSRNOP00000008952'],
      dtype='object', name='prots')

透视并将列按正确顺序设置:

In [175]: df_rat1 = df.pivot(index='chemicals', columns='prots', values='scores').fillna('')

In [176]: df_rat1 = df_rat1[cols]

In [177]: df_rat1
Out[177]:
prots        10116.ENSRNOP00000003921 10116.ENSRNOP00000001021 10116.ENSRNOP00000004027 10116.ENSRNOP00000008952
chemicals
CID000000006                      196
CID000000051                      246
CID000000085                      196
CID000000119                      247
CID000000134                                                                                                 159
CID000000135                                                                                                 157
CID000000174                                                                                                 439
CID000000175                                               858
CID000000177                                                                        760

第170行总是让我收到“AttributeError:'DataFrame'对象没有'sort_values'属性”的错误消息。 - user5103234
@ELWalou,尝试使用sort而不是sort_values。你可能正在使用较旧版本的pandas。 - jtitusj
@ELWalou,你使用的pandas版本是哪个? - MaxU - stand with Ukraine
@MaxU '0.14.1' (我没有root权限) - user5103234
@ELWalou,就像John所说的那样,使用.sort()而不是.sort_values() - MaxU - stand with Ukraine

0

我认为你需要使用sort_valuesnotnull进行排序并使用sum获取索引到cols。最后使用subset

df1 = df.pivot(index='chemicals', columns='proteins', values='scores')

cols = df1.notnull().sum(axis=0).sort_values(ascending=False).index
print cols
Index([u'10116.ENSRNOP00000003921', u'10116.ENSRNOP00000008952',
       u'10116.ENSRNOP00000004027', u'10116.ENSRNOP00000001021'],
      dtype='object', name=u'proteins')

print df1[cols]
proteins      10116.ENSRNOP00000003921  10116.ENSRNOP00000008952  \
chemicals                                                          
CID000000006                     196.0                       NaN   
CID000000051                     246.0                       NaN   
CID000000085                     196.0                       NaN   
CID000000119                     247.0                       NaN   
CID000000134                       NaN                     159.0   
CID000000135                       NaN                     157.0   
CID000000174                       NaN                     439.0   
CID000000175                       NaN                       NaN   
CID000000177                       NaN                       NaN   

proteins      10116.ENSRNOP00000004027  10116.ENSRNOP00000001021  
chemicals                                                         
CID000000006                       NaN                       NaN  
CID000000051                       NaN                       NaN  
CID000000085                       NaN                       NaN  
CID000000119                       NaN                       NaN  
CID000000134                       NaN                       NaN  
CID000000135                       NaN                       NaN  
CID000000174                       NaN                       NaN  
CID000000175                       NaN                     858.0  
CID000000177                     760.0                       NaN  

或者使用reindex_axis
print df1.reindex_axis(cols, axis=1)
proteins      10116.ENSRNOP00000003921  10116.ENSRNOP00000008952  \
chemicals                                                          
CID000000006                     196.0                       NaN   
CID000000051                     246.0                       NaN   
CID000000085                     196.0                       NaN   
CID000000119                     247.0                       NaN   
CID000000134                       NaN                     159.0   
CID000000135                       NaN                     157.0   
CID000000174                       NaN                     439.0   
CID000000175                       NaN                       NaN   
CID000000177                       NaN                       NaN   

proteins      10116.ENSRNOP00000004027  10116.ENSRNOP00000001021  
chemicals                                                         
CID000000006                       NaN                       NaN  
CID000000051                       NaN                       NaN  
CID000000085                       NaN                       NaN  
CID000000119                       NaN                       NaN  
CID000000134                       NaN                       NaN  
CID000000135                       NaN                       NaN  
CID000000174                       NaN                       NaN  
CID000000175                       NaN                     858.0  
CID000000177                     760.0                       NaN  

你的代码第二行的 "sort_values()" 函数里面是不是缺少了什么东西? 我得到的错误信息是:'NoneType' 对象没有属性 'index'。 - user5103234
我使用的是 pandas 0.18.0 版本。我认为问题可能出在使用较旧的版本上。 - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接