Python pandas 按枚举类值对数据帧进行排序

use*_*309 4 sorting enums python-3.x pandas categorical-data

如果我有枚举类:

from enum import Enum
class Colors(Enum):
    RED = 1
    ORANGE = 2
    GREEN = 3
Run Code Online (Sandbox Code Playgroud)

如果我有一个数据框,它的一列是颜色(它可以是小写的):

>>> import pandas as pd
>>> df = pd.DataFrame({'X':['A', 'B', 'C', 'A'], 'color' : ['GREEN', 'RED', 'ORANGE', 'ORANGE']})
>>> df
   X   color
0  A   GREEN
1  B     RED
2  C  ORANGE
3  A  ORANGE
Run Code Online (Sandbox Code Playgroud)

如何将颜色列作为尊重颜色类值的分类类型,并按“颜色”和“X”(升序)对数据框进行排序?

例如,上面的数据框应该排序为:

X, color
--------
B, RED
A, ORANGE
C, ORANGE
A, GREEN
Run Code Online (Sandbox Code Playgroud)

Tom*_*Tom 8

结合这个答案这一个使用:pd.Categorical由排序Colors类(有轻微的编辑更改其str):

from enum import Enum
import pandas as pd

df = pd.DataFrame({'X':['A', 'B', 'C', 'A'], 'color' : ['GREEN', 'RED', 'ORANGE', 'ORANGE']})

class Colors(Enum):
    RED = 1
    ORANGE = 2
    GREEN = 3
    def __str__(self):
        return self.name

df['color'] = pd.Categorical(df['color'], [str(i) for i in Colors], ordered=True)
df = df.sort_values(['color','X'])
Run Code Online (Sandbox Code Playgroud)

结果:

   X   color
1  B     RED
3  A  ORANGE
2  C  ORANGE
0  A   GREEN
Run Code Online (Sandbox Code Playgroud)


Dav*_*rex 5

使用getattr

df["value"] = df["color"].apply(lambda x: getattr(Colors, x).value)
df.sort_values(by=['value',"X"])
Run Code Online (Sandbox Code Playgroud)

输出:

    X   color   value
1   B   RED     1
3   A   ORANGE  2
2   C   ORANGE  2
0   A   GREEN   3
Run Code Online (Sandbox Code Playgroud)

在一行中(并且没有创建值列):

df.iloc[pd.concat([df["X"], df["color"].apply(lambda x: getattr(Colors, x))], axis=1).sort_values(by=['color',"X"]).index]
Run Code Online (Sandbox Code Playgroud)

输出:

    X   color
1   B   RED
3   A   ORANGE
2   C   ORANGE
0   A   GREEN
Run Code Online (Sandbox Code Playgroud)

  • 我还会考虑将“Colors(Enum)”更改为“Colors(IntEnum)”,因为它可以在排序函数中使用,而无需调用属性的“value”。 (3认同)