按星期几对ISO 8601中的熊猫数据框进行排序

时间:2019-03-17 19:00:06

标签: pandas datetime iso8601

我想按包含星期几ISO-8601表示的列对Pandas数据框进行排序。

df = pd.DataFrame([
    { 'day': 'Mon', 'value': 13 },
    { 'day': 'Wed', 'value': 24 },
    { 'day': 'Fri', 'value': 52 },
    { 'day': 'Sun', 'value': 56 },
    { 'day': 'Sat', 'value': 42 },
    { 'day': 'Thu', 'value': 84 },
    { 'day': 'Tue', 'value': 59 }
])

df['dt_'] = pd.to_datetime(df['day'], format='%a', errors='coerce')
df = df.sort_values('dt_')

>>> print(df)
   day  value        dt_
0  Mon     13 1900-01-01
1  Wed     24 1900-01-01
2  Fri     52 1900-01-01
3  Sun     56 1900-01-01
4  Sat     42 1900-01-01
5  Thu     84 1900-01-01
6  Tue     59 1900-01-01

很明显,预期的行为是将数据帧按Mon Tue Wed Thu Fri Sat Sun进行排序。根据{{​​3}},这种%a格式似乎是正确的。

除了包含day -> number的Dict外,还有没有更干净的方法来实现这一目标?

在此示例中使用星期几的缩写(Dy ISO-8601),但理想情况下,我希望采用通用解决方案来处理任何ISO-8601输入。

3 个答案:

答案 0 :(得分:2)

我知道如何处理这种情况的最干净的方法是使用daycategory列转换为熊猫ordered=True数据类型,并手动施加所需的排序顺序:

df['day'] = pd.Categorical(df['day'], ordered=True, 
                           categories=['Mon', 'Tue', 'Wed', 'Thu',
                                       'Fri', 'Sat', 'Sun'])

df = df.sort_values(by='day').reset_index(drop=True)
df
   day  value
0  Mon     13
1  Tue     59
2  Wed     24
3  Thu     84
4  Fri     52
5  Sat     42
6  Sun     56

day列现在具有dtype category和已定义的排序顺序:

df['day']
0    Mon
1    Tue
2    Wed
3    Thu
4    Fri
5    Sat
6    Sun
Name: day, dtype: category
Categories (7, object): [Mon < Tue < Wed < Thu < Fri < Sat < Sun]

答案 1 :(得分:2)

我尝试了其他方法,因此将其发布:

import calendar
d={i[:3]:e+1 for e,i in enumerate(list(calendar.day_name))}
#{'Mon': 1, 'Tue': 2, 'Wed': 3, 'Thu': 4, 'Fri': 5, 'Sat': 6, 'Sun': 7}
df['day_num']=df.day.map(d)
df.sort_values('day_num')

   day  value        dt_  day_num
0  Mon     13 1900-01-01        1
6  Tue     59 1900-01-01        2
1  Wed     24 1900-01-01        3
5  Thu     84 1900-01-01        4
2  Fri     52 1900-01-01        5
4  Sat     42 1900-01-01        6
3  Sun     56 1900-01-01        7

答案 2 :(得分:2)

我建议您使用mapnp.argsort而不更改原始数据类型,这实际上更安全

dayOfWeek={'Mon':0, 'Tue':1,'Wed':2,'Thu':3,'Fri':4,'Sat':5,'Sun':6}
df.iloc[np.argsort(df.day.map(dayOfWeek)),:]
   day  value
0  Mon     13
6  Tue     59
1  Wed     24
5  Thu     84
2  Fri     52
4  Sat     42
3  Sun     56