我想按包含星期几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输入。
答案 0 :(得分:2)
我知道如何处理这种情况的最干净的方法是使用day
将category
列转换为熊猫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)
我建议您使用map
和np.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