Python Pandas:如何使用运输智能卡数据将行程段组合到旅程中
目前正在使用一个有趣的交通智能卡数据集。当前数据中的每条线路代表一次跳闸(例如,从a到B的母线跳闸)。60分钟内的任何行程都需要分组为行程 当前表格:Python Pandas:如何使用运输智能卡数据将行程段组合到旅程中,python,pandas,transport,Python,Pandas,Transport,目前正在使用一个有趣的交通智能卡数据集。当前数据中的每条线路代表一次跳闸(例如,从a到B的母线跳闸)。60分钟内的任何行程都需要分组为行程 当前表格: CustomerID SegmentID Origin Dest StartTime EndTime Fare Type 0 A001 101 A B 7:30am 7:45am 1.5 Bus 1 A001 102 B C
CustomerID SegmentID Origin Dest StartTime EndTime Fare Type
0 A001 101 A B 7:30am 7:45am 1.5 Bus
1 A001 102 B C 7:50am 8:30am 3.5 Train
2 A001 103 C B 17:10pm 18:00pm 3.5 Train
3 A001 104 B A 18:10pm 18:30pm 1.5 Bus
4 A002 105 K Y 11:30am 12:30pm 3.0 Train
5 A003 106 P O 10:23am 11:13am 4.0 Ferrie
然后变成这样:
CustomerID JourneyID Origin Dest Start Time End Time Fare Type NumTrips
0 A001 1 A C 7:30am 8:30am 5 Intermodal 2
1 A001 2 C A 17:10pm 18:30pm 5 Intermodal 2
2 A002 6 K Y 11:30am 12:30pm 3 Train 1
3 A003 8 P O 10:23am 11:13am 4 Ferrie 1
我不熟悉Python和Pandas,不知道如何开始,因此希望您能提供任何指导。这里有一个相当完整的答案。你没有详细说明单程旅行的概念,所以我猜了一下。您可以调整下面的遮罩,以更好地适应您自己的定义
# get rid of am/pm and convert to proper datetime
# converts to year 1900 b/c it's not specified, doesn't matter here
df['StTime'] = pd.to_datetime( df.StartTime.str[:-2], format='%H:%M' )
df['EndTime'] = pd.to_datetime( df.EndTime.str[:-2], format='%H:%M' )
# some of the later processing is easier if you use duration
# instead of arrival time
df['Duration'] = df.EndTime-df.StTime
# get rid of some nuisance variables for clarity
df = df[['CustomerID','Origin','Dest','StTime','Duration','Fare','Type']]
首先,我们需要找出一种将行分组的方法。由于这在问题中没有明确说明,我将按客户ID分组,其中开始时间在1小时之内。请注意,对于三种模式的出行,这实际上意味着只要第一次+第二次+第三次出行的开始时间分别小于1小时,第一次和第三次出行的开始时间的差异可能大于1小时。这似乎是一种自然的方式,但是对于您的实际用例,您必须根据您想要的定义调整它。这里有很多方法可以继续
mask1 = df.StTime - df.StTime.shift(1) <= pd.Timedelta('01:00:00')
mask2 = (df.CustomerID == df.CustomerID.shift(1))
mask = ( mask1 & mask2 )
现在,对于每一列,只需适当地聚合:
df2 = df.groupby('JourneyID').agg({ 'Origin' : sum, 'CustomerID' : min,
'Dest' : sum, 'StTime' : min,
'Fare' : sum, 'Duration' : sum,
'Type' : sum, 'NumTrips' : sum })
StTime Dest Origin Fare Duration Type CustomerID NumTrips
JourneyID
1 1900-01-01 07:30:00 BC AB 5 00:55:00 BusTrain A001 2
2 1900-01-01 17:10:00 BA CB 5 01:10:00 TrainBus A001 2
3 1900-01-01 11:30:00 Y K 3 01:00:00 Train A002 1
4 1900-01-01 10:23:00 O P 4 00:50:00 Ferrie A003 1
请注意,持续时间仅包括行程时间,而不包括两次行程之间的时间(例如,如果第二次行程的开始时间晚于第一次行程的结束时间)。以下是一个相当完整的答案。你没有详细说明单程旅行的概念,所以我猜了一下。您可以调整下面的遮罩,以更好地适应您自己的定义
# get rid of am/pm and convert to proper datetime
# converts to year 1900 b/c it's not specified, doesn't matter here
df['StTime'] = pd.to_datetime( df.StartTime.str[:-2], format='%H:%M' )
df['EndTime'] = pd.to_datetime( df.EndTime.str[:-2], format='%H:%M' )
# some of the later processing is easier if you use duration
# instead of arrival time
df['Duration'] = df.EndTime-df.StTime
# get rid of some nuisance variables for clarity
df = df[['CustomerID','Origin','Dest','StTime','Duration','Fare','Type']]
首先,我们需要找出一种将行分组的方法。由于这在问题中没有明确说明,我将按客户ID分组,其中开始时间在1小时之内。请注意,对于三种模式的出行,这实际上意味着只要第一次+第二次+第三次出行的开始时间分别小于1小时,第一次和第三次出行的开始时间的差异可能大于1小时。这似乎是一种自然的方式,但是对于您的实际用例,您必须根据您想要的定义调整它。这里有很多方法可以继续
mask1 = df.StTime - df.StTime.shift(1) <= pd.Timedelta('01:00:00')
mask2 = (df.CustomerID == df.CustomerID.shift(1))
mask = ( mask1 & mask2 )
现在,对于每一列,只需适当地聚合:
df2 = df.groupby('JourneyID').agg({ 'Origin' : sum, 'CustomerID' : min,
'Dest' : sum, 'StTime' : min,
'Fare' : sum, 'Duration' : sum,
'Type' : sum, 'NumTrips' : sum })
StTime Dest Origin Fare Duration Type CustomerID NumTrips
JourneyID
1 1900-01-01 07:30:00 BC AB 5 00:55:00 BusTrain A001 2
2 1900-01-01 17:10:00 BA CB 5 01:10:00 TrainBus A001 2
3 1900-01-01 11:30:00 Y K 3 01:00:00 Train A002 1
4 1900-01-01 10:23:00 O P 4 00:50:00 Ferrie A003 1
请注意,持续时间仅包括旅行时间,不包括两次旅行之间的时间(例如,如果第二次旅行的开始时间晚于第一次旅行的结束时间)。您确定要将旅行定义为一小时内的任何一组旅行,而不是在家开始/结束的全天旅行吗?是。。。一小时内的旅行勾选这些答案,您确定要将旅行定义为一小时内的任何一组旅行,而不是在家开始/结束的全天旅行吗?是的。。。一小时内的行程勾选这些答案,然后