我想通过以下代码更改订单日期 我想要的是订单(周一,周二,周三,周四,周五,周六,周日)的结果 - 我应该说,按照某个预定顺序按键排序?
这是我需要调整的代码:
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()
,但它是一个按值组建的内置排序函数。
我想得到一些指示来设置一些命令来使用它进一步的数据操作
提前谢谢。
答案 0 :(得分:15)
花了我一些时间,但我找到了解决方案。 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')
或更方便(归功于burhan)
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
答案 1 :(得分:4)
将'day'
列设置为categorical 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()
更新 :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'
,您只需执行相同类型的过程:将列指定为分类,您的类别采用您想要的非标准顺序。
答案 2 :(得分:1)
可能不是最好的方法,但就我所知,你无法将函数/映射传递给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
答案 3 :(得分:1)
如果您对groupby
之前的数据框进行排序,则pandas将维护您的排序顺序。你要做的第一件事是提出一个很好的方法来排序一周的日子。一种方法是将表示星期几的int分配给每一行,然后对该列进行排序。例如:
import pandas
df = pandas.DataFrame(
columns=['device_id', 'day', 'dwell_time'],
data=[[1, 'Wed', 35], [1, 'Mon', 63], [2, 'Sat', 83], [2, 'Fri', 82]]
)
df['day_of_week'] = df.apply(
lambda x: ['Mon', 'Tues', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'].index(x.day),
1
)
print(df.sort(['device_id', 'day_of_week']).groupby(['device_id', 'day'])['dwell_time'].sum())
的产率:
device_id day dwell_time
1 Mon 63
Wed 35
2 Fri 82
Sat 83