熊猫:通过将负载重量与相应的负载重量配对来识别卡车路线中的多路“到达目的地”

时间:2019-01-18 03:42:34

标签: python pandas dataframe

摘要:下面的第一个数据框列出了卡车司机进行的多次行程的每条腿,按时间顺序排序,并按行程ID分组。我需要一种方法,将每个重要的货物装卸与相应的卸货配对,以将其压缩为单个货物。由于真实的数据框包含数百万条记录,因此,如果我想保持理智,我可以肯定地说,我需要在不进行迭代的情况下执行此操作。

复杂因素: -给定交付的onload和offload值并不总是完美的匹配 -有时会有一些定位腿,在此过程中没有人搬运货物(我想避免抓住这些东西)

假设: -没有重叠的交付;交付始终在开始新交付之前完成 -卸载永远不会在多个目标上广泛传播

但是,如果您的解决方案在不做上述假设的情况下工作,那么我将要求各地的所有人永远支持您。从现在开始的40年后,我将向人们介绍“嗨!我是光度。很高兴认识你。请点击这张名片上的链接,并在答案旁边打上绿色对勾,以表扬自己。”

除非事实证明解决方案是非常简单的,否则我会很尴尬地解决。


因此,从一开始。我正在处理货车运输路线上的数据。任何给定的卡车通常都会进行多程行程,包括多次货物运输,其中卡车在A点接货,在B点卸货,再接更多,在C点卸货,等等。我拥有的数据清单多次行程,并按重量列出每次行程的每条腿以及其货物的装卸量,大致如下:

import pandas as pd

df = pd.DataFrame([['ABC12321','1 Jan','2 Jan','Point A','Point B',100,  0],
                   ['ABC12321','2 Jan','2 Jan','Point B','Point C',  0,100],
                   ['ABC12321','2 Jan','2 Jan','Point C','Point D',150,  0],
                   ['ABC12321','3 Jan','3 Jan','Point D','Point E',  0,150],
                   ['QRS32123','2 Jan','2 Jan','Point Q','Point R', 50,  0],
                   ['QRS32123','2 Jan','3 Jan','Point R','Point S',  0, 50],
                   ['QRS32123','3 Jan','3 Jan','Point S','Point T', 75,  0],
                   ['QRS32123','3 Jan','4 Jan','Point T','Point U',  0,  0],
                   ['QRS32123','4 Jan','5 Jan','Point U','Point V',  0,  2],
                   ['QRS32123','5 Jan','6 Jan','Point V','Point W',  0, 73]],
           columns=['Trip_ID','Start_Date','End_Date','Start_Location','End_Location','Onload','Offload'])

print(df)

    Trip_ID Start_Date End_Date Start_Location End_Location  Onload  Offload
0  ABC12321      1 Jan    2 Jan        Point A      Point B     100        0
1  ABC12321      2 Jan    2 Jan        Point B      Point C       0      100
2  ABC12321      2 Jan    2 Jan        Point C      Point D     150        0
3  ABC12321      3 Jan    3 Jan        Point D      Point E       0      150
4  QRS32123      2 Jan    2 Jan        Point Q      Point R      50        0
5  QRS32123      2 Jan    3 Jan        Point R      Point S       0       50
6  QRS32123      3 Jan    3 Jan        Point S      Point T      75        0
7  QRS32123      3 Jan    4 Jan        Point T      Point U       0        0
8  QRS32123      4 Jan    5 Jan        Point U      Point V       0        2
9  QRS32123      5 Jan    6 Jan        Point V      Point W       0       73

我想要的是通过将负载重量与其对应的负载重量配对来将其压缩为单个交货。如果成功,上述数据框将产生以下结果:

    Trip_ID Start_Date End_Date Start_Location End_Location
0  ABC12321      1 Jan    2 Jan        Point A      Point C
1  ABC12321      2 Jan    3 Jan        Point C      Point E
2  QRS32123      2 Jan    3 Jan        Point Q      Point S
3  QRS32123      3 Jan    6 Jan        Point S      Point W

如果每个行程ID只有一个重要的上载和下载,这将非常简单;我将获得所有记录,其中onload达到了被认为是有意义的最小阈值,然后是相同的卸载,然后将它们合并在一起,就像这样:

# If starting from this:
df = pd.DataFrame([['ABC12321','1 Jan','2 Jan','Point A','Point B',100,  0],
                   ['ABC12321','2 Jan','2 Jan','Point B','Point C',  0,100],
                   ['QRS32123','3 Jan','3 Jan','Point S','Point T', 75,  0],
                   ['QRS32123','3 Jan','4 Jan','Point T','Point U',  0,  0],
                   ['QRS32123','4 Jan','5 Jan','Point U','Point V',  0,  2],
                   ['QRS32123','5 Jan','6 Jan','Point V','Point W',  0, 73]],
           columns=['Trip_ID','Start_Date','End_Date','Start_Location','End_Location','Onload','Offload'])

# ...Then do this:
df2 = df.loc[df['Onload']>5,['Trip_ID','Start_Date','Start_Location',]]
df3 = df.loc[df['Offload']>5,['Trip_ID','End_Date','End_Location',]]
df_final = df2.merge(df3, how='left', on='Trip_ID')
df_final = df_final.reindex(columns=['Trip_ID','Start_Date','End_Date','Start_Location','End_Location'])

...导致以下结果:

print(df)

    Trip_ID Start_Date End_Date Start_Location End_Location  Onload  Offload
0  ABC12321      1 Jan    2 Jan        Point A      Point B     100        0
1  ABC12321      2 Jan    2 Jan        Point B      Point C       0      100
2  QRS32123      3 Jan    3 Jan        Point S      Point T      75        0
3  QRS32123      3 Jan    4 Jan        Point T      Point U       0        0
4  QRS32123      4 Jan    5 Jan        Point U      Point V       0        2
5  QRS32123      5 Jan    6 Jan        Point V      Point W       0       73

print(df2)

    Trip_ID Start_Date Start_Location
0  ABC12321      1 Jan        Point A
2  QRS32123      3 Jan        Point S

print(df3)

    Trip_ID End_Date End_Location
1  ABC12321    2 Jan      Point C
5  QRS32123    6 Jan      Point W

print(df_final)

    Trip_ID Start_Date End_Date Start_Location End_Location
0  ABC12321      1 Jan    2 Jan        Point A      Point C
1  QRS32123      3 Jan    6 Jan        Point S      Point W

但是我不仅必须处理每次旅行的多次交付,而且我无法提前知道有多少交付。有时也有一些定位腿,没有货物运载,所以我不能只是取消卸载,而假设卸载后的下一个记录是下一次交货的开始。

即使那样,如果负载和它们对应的负载完全匹配并且在给定行程中始终是唯一的,我也可以通过简单地同时标记行程ID和负载/负载将它们配对。但是它们并不总是完全匹配(请参阅上面的最后一趟),并且给定的行程完全可能涉及多个重量相同的重量的卸载和卸载。

非常感谢,我至少可以保证每次旅行的腿都按时间顺序排序。因此,我目前考虑解决单程行程问题的策略是:

  1. 遍历行,直到找到超过给定(静态)阈值的上载值,然后将该行的“行程ID”,“开始日期”和“开始位置”写入单独数据框中的新行。
  2. 检查我刚刚找到的行是否还包含超出阈值的卸载。
    • 如果没有,请遍历其余行,直到发现超过我的阈值的卸载为止。
    • 无论哪种情况,都请使用该行的“结束日期”和“结束位置”来填写步骤1中的新行。
  3. 重复执行,直到选中该旅行ID的最后一行。

但是现在我有两个新问题:1)我不确定如何以这种“从左到右”的方式进行迭代(此时我的大脑已被射中),以及2)我想遍历数百万行。这将花费很多时间,而我将需要多次运行它。

所以!有没有更好的方法来实现这一点?

0 个答案:

没有答案