按特定顺序排序(情况:pandas DataFrame Groupby)

2024-05-16 03:10:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我想更改以下代码显示的订单日期。
我想要的是订单的结果(周一、周二、周三、周四、周五、周六、周日)
-我应该说,按某个预定义的顺序按键排序吗?


这是我的代码,需要调整一下:

f8 = df_toy_indoor2.groupby(['device_id', 'day'])['dwell_time'].sum()

print(f8)

当前结果:

device_id                         day
device_112                        Thu     436518
                                  Wed     636451
                                  Fri     770307
                                  Tue     792066
                                  Mon     826862
                                  Sat     953503
                                  Sun    1019298
device_223                        Mon    2534895
                                  Thu    2857429
                                  Tue    3303173
                                  Fri    3548178
                                  Wed    3822616
                                  Sun    4213633
                                  Sat    4475221

预期结果:

device_id                         day
device_112                        Mon     826862  
                                  Tue     792066
                                  Wed     636451 
                                  Thu     436518
                                  Fri     770307
                                  Sat     953503
                                  Sun    1019298
device_223                        Mon    2534895
                                  Tue    3303173
                                  Wed    3822616
                                  Thu    2857429
                                  Fri    3548178
                                  Sat    4475221
                                  Sun    4213633

这里,type(df_toy_indoor2.groupby(['device_id', 'day'])['dwell_time'])是一个“pandas.core.groupby.SeriesGroupBy”类。

我找到了.sort_values(),但它是一个内置的按值排序函数。
我想让一些指针来设置一些顺序,以便使用它进一步处理数据。
提前谢谢。


Tags: 代码订单id排序顺序devicesatsun
3条回答

'day'列设置为categorical数据类型,只需确保在设置类别时,天数列表按您希望的顺序排序。然后,执行groupby将自动为您排序,但如果您尝试对列进行排序,则它将按照指定的正确顺序进行排序。

# Initial setup.
np.random.seed([3,1415])
n = 100
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
df = pd.DataFrame({
    'device_id': np.random.randint(1,3,n),
    'day': np.random.choice(days, n),
    'dwell_time':np.random.random(n)
    })


# Set as category, groupby, and sort.
df['day'] = df['day'].astype("category", categories=days, ordered=True)
df = df.groupby(['device_id', 'day']).sum()

更新:astype不再接受类别,使用:

category_day = pd.api.types.CategoricalDtype(categories=days, ordered=True)
df['day'] = df['day'].astype(category_day)

结果输出:

               dwell_time
device_id day            
1         Mon    4.428626
          Tue    3.259319
          Wed    2.436024
          Thu    0.909724
          Fri    4.974137
          Sat    5.583778
          Sun    2.687258
2         Mon    3.117923
          Tue    2.427154
          Wed    1.943927
          Thu    4.599547
          Fri    2.628887
          Sat    6.247520
          Sun    2.716886

请注意,此方法适用于任何类型的自定义排序。例如,如果有一个列的条目是'a', 'b', 'c',并且希望它按非标准顺序排序,例如'c', 'a', 'b',那么您只需执行相同类型的过程:将该列指定为categorical,而您的类别则按所需的非标准顺序。

可能不是最好的方法,但据我所知,不能将函数/映射传递给sort_values。作为解决方法,我通常使用assign添加新列并按该列排序。在您的示例中,这还需要先重置索引(并将其设置回原来的位置)。

days = {'Mon': 1, 'Tue': 2, 'Wed': 3, 'Thu': 4, 'Fri': 5, 'Sun': 6, 'Sat': 7}
f8 = f8.reset_index()
(f8.assign(day_num=f8['day'].map(days))
   .sort_values(['device_id', 'day_num'])
   .set_index(['device_id', 'day'])
   .drop('day_num', axis=1))
Out: 
                                            0
device_id                        day         
0d4fd55bb363bf6f6f7f8b3342cd0467 Mon   826862
                                 Tue   792066
                                 Wed   636451
                                 Thu   436518
                                 Fri   770307
                                 Sun  1019298
                                 Sat   953503
f6258edf9145d1c0404e6f3d7a27a29d Mon  2534895
                                 Tue  3303173
                                 Wed  3822616
                                 Thu  2857429
                                 Fri  3548178
                                 Sun  4213633
                                 Sat  4475221

花了我一些时间,但我找到了解决办法。reindex做你想做的事。请参阅我的代码示例:

a = [1, 2] * 2 + [2, 1] * 3 + [1, 2]
b = ['Mon', 'Wed', 'Thu', 'Fri'] * 3
c = list(range(12))
df = pd.DataFrame(data=[a,b,c]).T
df.columns = ['device', 'day', 'value']
df = df.groupby(['device', 'day']).sum()

给出:

            value
device day       
1      Fri      7
       Mon      0
       Thu     12
       Wed     14
2      Fri     14
       Mon     12
       Thu      6
       Wed      1

然后重新编制索引:

df.reindex(['Mon', 'Wed', 'Thu', 'Fri'], level='day')

或者更方便(博汉的功劳)

df.reindex(list(calendar.day_abbr), level='day')

给出:

            value
device day       
1      Mon      0
       Wed     14
       Thu     12
       Fri      7
2      Mon     12
       Wed      1
       Thu      6
       Fri     14

相关问题 更多 >