问题描述
我有顺序数据,其中列名反映了每行 A 到 B 点序列的值。
Segment
应该表示行程段顺序,并且只能以偶数增量出现。即,假设 Segment 0
应该代表 Segment 2
之前的一条腿,它应该在 Segment 4
之前,等等。组合起来,这些段将构成一个单向序列(出站/返回)。但是,对该字段的检查表明该字段并不总是可信的:
- 初始行程段似乎始终为
0
,但也有多个0
段行程无法验证哪个是“真实”初始行程段的情况。 - 有时
Segments
会跳过偶数 - 意思是,对于给定的Personnel_ID
,Segments
可能是例如,如下面的玩具数据,[0,2,10,12]
。立> - 似乎在大多数情况下,后续行程的
Segment
值都在增加,但下面的指数 14 显示了一个例外。
df = pd.DataFrame({'Personnel_ID':pd.Series(['AB1234']).repeat(10),'Segment':[0,8,12,4,6],'Origin_Depart_Date': ['2020-05-16','2020-05-16','2020-05-17','2020-06-04','2020-06-04'],'Origin':['Indianapolis','Indianapolis','Zanesville','athens','Chicago','Fredericksburg','Jacksonville'],'Destination':['Zanesville','Jacksonville','Indianapolis']})
df2 = pd.DataFrame({'Personnel_ID':pd.Series(['BC5678']).repeat(7),'Origin_Depart_Date':['2020-05-08','2020-05-08','2020-05-19','2020-05-19'],'Seattle','athens'],'Destination':['athens','Indianapolis']})
df = pd.concat([df,df2])
df['Origin_Depart_Date'] = pd.to_datetime(df['Origin_Depart_Date'],format = '%Y-%m-%d')
目标:为数据中的每次往返创建一个唯一 ID,其中连接段之间可能存在 1 天的延迟。
理想情况下,我希望能够在每次往返中区分出境和回程。
出境旅行被定义为每 Origin
行的 Destination
和 Personnel_ID
行序列,可以在 2 天内发生,其中 Origin
与 { {1}}。
回程被定义为每 Destination
行的 Destination
和 Origin
行序列,可以在 2 天内发生,其中 Personnel_ID
与 { {1}}。
往返是出站和回程的配对,没有时间限制,此时Destination
和Origin
是相等的。
我最初只是尝试识别出站和回程:
Origin
以上依赖于上述观察,Destination
可以被信任为旅行的第一段,然后根据按出发日期和段号排序的旅行段转发填充。
它显然没有包含任何时间窗口来关联连续几天发生的旅行(指数 14 比 1)。
def uid(x): return x['Personnel_ID'] + '_' + str(x['Segment']) + '_' + x['Origin_Depart_Date'].strftime('%Y-%m-%d') + '_' + x['Origin']
df.insert(0,'uid',(df[df['Segment']==0]).apply(lambda x: uid(x),axis=1))
df = df.sort_values(['uid','Segment'])
dupe_PIDs = df[df.duplicated(['Personnel_ID','Segment','Origin_Depart_Date'])]['Personnel_ID']
df = df[~df['Personnel_ID'].isin(dupe_PIDs)].reset_index()
df = df.sort_values(['Personnel_ID','Origin_Depart_Date','Segment'])
df['uid'] = df['uid'].ffill()
df.drop('level_0',axis=1).sort_values(['Personnel_ID','Segment']).to_clipboard(sep='\t')
所以我认为尝试结合日期检查和0
的布尔掩码可能更有效(尽管它确实带来了如何区分出站与返回的问题) :
uid Personnel_ID Segment Origin_Depart_Date Origin Destination
0 AB1234_0_2020-05-16_Indianapolis AB1234 0 2020-05-16 Indianapolis Zanesville
14 AB1234_0_2020-05-16_Indianapolis AB1234 8 2020-05-16 Indianapolis Zanesville
1 AB1234_0_2020-05-17_Zanesville AB1234 0 2020-05-17 Zanesville athens
6 AB1234_0_2020-05-17_Zanesville AB1234 2 2020-05-17 athens Chicago
15 AB1234_0_2020-05-17_Zanesville AB1234 10 2020-05-17 Zanesville athens
16 AB1234_0_2020-05-17_Zanesville AB1234 12 2020-05-17 athens Chicago
2 AB1234_0_2020-06-04_Chicago AB1234 0 2020-06-04 Chicago athens
7 AB1234_0_2020-06-04_Chicago AB1234 2 2020-06-04 athens Fredericksburg
10 AB1234_0_2020-06-04_Chicago AB1234 4 2020-06-04 Fredericksburg Jacksonville
12 AB1234_0_2020-06-04_Chicago AB1234 6 2020-06-04 Jacksonville Indianapolis
3 BC5678_0_2020-05-08_Indianapolis BC5678 0 2020-05-08 Indianapolis athens
8 BC5678_0_2020-05-08_Indianapolis BC5678 2 2020-05-08 athens Seattle
4 BC5678_0_2020-05-16_Seattle BC5678 0 2020-05-16 Seattle athens
5 BC5678_0_2020-05-19_Seattle BC5678 0 2020-05-19 Seattle athens
9 BC5678_0_2020-05-19_Seattle BC5678 2 2020-05-19 athens Indianapolis
11 BC5678_0_2020-05-19_Seattle BC5678 4 2020-05-19 Seattle athens
13 BC5678_0_2020-05-19_Seattle BC5678 6 2020-05-19 athens Indianapolis
然而,这会丢弃 Origin==Destination
,这是不受欢迎的行为。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)