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

SUN*_*ONG 9 python sorting pandas

我想更改下面代码提供的订单日期.
我想要的是订单(周一,周二,周三,周四,周五,周六,周日)的结果
- 我应该说,按照某个预定顺序按键排序?


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

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

print(f8)
Run Code Online (Sandbox Code Playgroud)

目前的结果:

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
Run Code Online (Sandbox Code Playgroud)

期望的结果:

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
Run Code Online (Sandbox Code Playgroud)

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

我找到了.sort_values(),但它是一个按值组建的内置排序函数.
我想得到一些指针来设置一些命令来使用它进一步的数据操作.
提前致谢.

Pde*_*evG 16

花了我一些时间,但我找到了解决方案.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()
Run Code Online (Sandbox Code Playgroud)

得到:

            value
device day       
1      Fri      7
       Mon      0
       Thu     12
       Wed     14
2      Fri     14
       Mon     12
       Thu      6
       Wed      1
Run Code Online (Sandbox Code Playgroud)

然后做reindex:

df.reindex(['Mon', 'Wed', 'Thu', 'Fri'], level='day')
Run Code Online (Sandbox Code Playgroud)

或者更方便(归功于burhan)

df.reindex(list(calendar.day_abbr), level='day')
Run Code Online (Sandbox Code Playgroud)

得到:

            value
device day       
1      Mon      0
       Wed     14
       Thu     12
       Fri      7
2      Mon     12
       Wed      1
       Thu      6
       Fri     14
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`calendar`模块并将reindex更改为:`df.reindex(list(calendar.day_abbr),level ='day')`以避免明确定义工作日. (2认同)

roo*_*oot 6

'day'列设置为分类dtype,只需确保在设置类别时,您的天数列表按您希望的方式排序。执行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()
Run Code Online (Sandbox Code Playgroud)

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

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

结果输出:

               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
Run Code Online (Sandbox Code Playgroud)

请注意,此方法适用于任何类型的自定义排序。例如,如果您有一个包含条目的列'a', 'b', 'c',并希望以非标准顺序对其进行排序,例如'c', 'a', 'b',您只需执行相同类型的过程:将列指定为 categorical 且您的类别属于非你想要的标准订单。