按列表顺序对pandas DataFrame排序

Wes*_*eld 1 sorting dataframe python-2.7 pandas

因此,我有一个熊猫DataFrame,df,其中的列表示生物分类(例如,Kingdom,Phylum,Class等)。我还有一个生物分类标签列表,这些标签与我希望对DataFrame进行排序的顺序相对应。

该列表如下所示:

class_list=['Gammaproteobacteria', 'Bacteroidetes', 'Negativicutes', 'Clostridia', 'Bacilli', 'Actinobacteria', 'Betaproteobacteria', 'delta/epsilon subdivisions', 'Synergistia', 'Mollicutes', 'Nitrospira', 'Spirochaetia', 'Thermotogae', 'Aquificae', 'Fimbriimonas', 'Gemmatimonadetes', 'Dehalococcoidia', 'Oscillatoriophycideae', 'Chlamydiae', 'Nostocales', 'Thermodesulfobacteria', 'Erysipelotrichia', 'Chlorobi', 'Deinococci']
Run Code Online (Sandbox Code Playgroud)

此列表将对应于Dataframedf['Class']。我想基于列表的顺序对整个数据框的所有行进行排序,因为当前的顺序df['Class']不同。最好的方法是什么?

Ale*_*ley 6

您可以将该Class列作为索引列

df = df.set_index('Class')
Run Code Online (Sandbox Code Playgroud)

然后使用df.loc重新索引DataFrame class_list

df.loc[class_list]
Run Code Online (Sandbox Code Playgroud)

最小示例:

>>> df = pd.DataFrame({'Class': ['Gammaproteobacteria', 'Bacteroidetes', 'Negativicutes'], 'Number': [3, 5, 6]})
>>> df
                 Class  Number
0  Gammaproteobacteria       3
1        Bacteroidetes       5
2        Negativicutes       6

>>> df = df.set_index('Class')
>>> df.loc[['Bacteroidetes', 'Negativicutes', 'Gammaproteobacteria']]
                     Number
Bacteroidetes             5
Negativicutes             6
Gammaproteobacteria       3
Run Code Online (Sandbox Code Playgroud)

  • 为了更好的通用性,请使用“df = df.reindex(some_list)”,请参阅[此处](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.reindex.html),用于重新索引步骤。虽然“DataFrame.loc[]”主要是基于标签的,但它也可以与布尔数组一起使用,详见[此处](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .DataFrame.loc.html)。因此,如果索引最终是布尔值,并且您尝试使用 df = df.loc[[True,False]] 重新索引,您最终将丢弃第二行。请参阅 /sf/answers/2100700311/。 (2认同)

小智 5

如果您的原始数据框不包含有序列表中的所有元素,则 Alex 的解决方案不起作用,即:如果您在某个时间点的输入数据不包含“Negativicutes”,则此脚本将失败。解决这个问题的一种方法是将您的 df 附加到列表中并在最后将它们连接起来。例如:

ordered_classes = ['Bacteroidetes', 'Negativicutes', 'Gammaproteobacteria']

df_list = []

for i in ordered_classes:
   df_list.append(df[df['Class']==i)

ordered_df = pd.concat(df_list)
Run Code Online (Sandbox Code Playgroud)