这是我关于StackOverflow的第一个问题,所以我尽量清晰简洁。非常感谢您的耐心等待。
背景
我有一个包含 17 个属性的训练数据数据集,这些属性包括:origin_station_code
、origin_station
、destination_station_code
、destination_station
、route_code
、start_time
、end_time
、fleet_number
、station_code
、station
、station_type
、platform
、sch_arr_time
、sch_dep_time
、act_arr_time
、act_dep_time
、date
。
在这些属性中,我只关心:date
、origin_station
、destination_station
和start_time
。
此数据集由 61 个单独的 CSV 文件组成,这些文件使用 glob 函数和循环组合在一起形成一个超过一百万行的数据帧。
数据帧的每一行表示火车旅程的各个停靠点。完整路径由多个停靠点组成,以下屏幕截图显示了由 19 个停靠点组成的路径示例,即从糖波到尝试 Pin:此处。
通过连接origin_station
和destination_station
属性,创建了一个名为complete_route name
的新属性。这可以识别所有路由,其中有 81 个唯一条目。
任务
我的任务是使用 pandas 对数据帧进行子集化,以便数据集显示每个日期最受欢迎的 3 条路由。此子集数据帧应显示date
、complete_route name
以及该路由每天发生的次数计数。通过将 nunique 方法应用于start_time
属性(日期/时间类型(,可以确定路径发生的唯一次数。
我目前的进度
目前,我的 GroupBy 和聚合代码能够显示每个路由每天运行的次数,如下所示:
df_grouped = df.groupby(
['date', 'complete_route_name']
).agg(
{
'start_time': 'nunique' # count the number of unique routes by using the 'nunique' of the start_times
}
).reset_index()
但是,我现在想现在使用我现有的代码,以便它每天仅按计数显示前 3 条唯一路由,例如
date complete_route_name count
2015-08-01 Attempt Pin to Roll Test 101
Suit Treatment Turnback to Spiders Toothbrush 93
Concourse Village to Port Morris 87
2015-08-02 Bridge Bottle to Ants Attempt 119
North Riverdale to Eastchester 117
Wakefield to Kingsbridge 101
......
2015-09-30 Castleton Corners to Dongan Hills 121
Eltingville to Graniteville 119
Great Kills to Castleton 117
任何这方面的帮助将不胜感激!
其他资源
原始数据集和当前状态的工作簿可以在我的 GitHub 上找到托管,如果它有任何用途/兴趣。也可以在此处查看静态工作簿。
非常感谢!
我会从你离开的地方继续
df_agg = df.groupby(['date', 'route_name']).agg({'start_time':'nunique'}).reset_index()
然后我会做以下事情来解决您的要求
df_sorted_by_group = df_agg.groupby(['date']).apply(
lambda x: x.sort_values(['start_time'],ascending = False)
).reset_index(drop = True)
最后一步
df_final = df_sorted_by_group.groupby(['date']).head(3)
示例代码
import pandas as pd
routes = {'route_name': [ 'A to B', 'A to B', 'B to C', 'B to C', 'C to D', 'C to D', 'C to D', 'C to D', 'D to E',
'A to Z', 'A to Z', 'B to Z', 'B to Z', 'C to Z', 'C to Z', 'C to Z', 'C to Z', 'D to Z'],
'date': ['01/01/2015','01/01/2015','01/01/2015','01/01/2015','01/01/2015','01/01/2015','01/01/2015','01/01/2015','01/01/2015',
'02/01/2015','02/01/2015','02/01/2015','02/01/2015','02/01/2015','02/01/2015','02/01/2015','02/01/2015','02/01/2015'],
'start_time': ['A1','A2','A3','A4','A5','A6','A7','A8','A9','A10','A11','A12','A13','A14','A15','A16','A17','A18']
}
df = pd.DataFrame(routes)
df['date'] = pd.to_datetime(df['date'],format ='%d/%m/%Y')
df
route_name date start_time
0 A to B 2015-01-01 A1
1 A to B 2015-01-01 A2
2 B to C 2015-01-01 A3
3 B to C 2015-01-01 A4
4 C to D 2015-01-01 A5
5 C to D 2015-01-01 A6
6 C to D 2015-01-01 A7
7 C to D 2015-01-01 A8
8 D to E 2015-01-01 A9
9 A to Z 2015-01-02 A10
10 A to Z 2015-01-02 A11
11 B to Z 2015-01-02 A12
12 B to Z 2015-01-02 A13
13 C to Z 2015-01-02 A14
14 C to Z 2015-01-02 A15
15 C to Z 2015-01-02 A16
16 C to Z 2015-01-02 A17
17 D to Z 2015-01-02 A18
从上面应用脚本后,您将获得以下结果
df_final
date route_name start_time
0 2015-01-01 C to D 4
1 2015-01-01 A to B 2
2 2015-01-01 B to C 2
4 2015-01-02 C to Z 4
5 2015-01-02 A to Z 2
6 2015-01-02 B to Z 2
df_sorted_by_group = df_grouped.groupby(['Date']).apply(
lambda x: x.sort_values(['Count'],ascending = False)
).reset_index(drop = True)
df_grouped_top16 = df_sorted_by_group.groupby(['Date']).head(16)
好的,所以从你的工作部分开始,我会把它重写为:
df_grouped = df.groupby(
['date', 'complete_route_name'], as_index=False
)['start_time'].nunique()
接下来,您可以执行以下操作:
df2=df_grouped.groupby("date").rank().le(3)
df_grouped.loc[df2.loc[df2].index]