簡體   English   中英

[Python, pandas]:每輛車每天跑公里

[英][Python, pandas]: get km run per day per vehicle

我正在嘗試 output 一個表,在那里我可以看到每輛車每天運行的公里數,但我得到的計算是錯誤的。

給出我所擁有的數據的一小部分。 每輛車每天將其當前里程表讀數發送到中央服務器數百次。

TS                          DATE               VEH          ODOMETER
2021-03-12 12:58:15.500     2021-03-12         008              2932
2021-03-12 00:00:21.700     2021-03-12         002             64253
2021-03-12 00:02:21.500     2021-03-12         002             64254
2021-03-12 00:03:41.400     2021-03-12         002             64255
2021-03-12 00:05:38.200     2021-03-12         002             64256
...                         ...                ...             ...
2021-03-12 23:55:88.100     2021-03-12         002             64953
2021-03-12 00:05:38.200     2021-03-13         002             64954

正如在上面的示例中應該清楚的那樣,車輛 2 在 2021 年 3 月 12 日的第一個和最后一個里程表讀數是 64953-64253 = 700 公里,但第二天的第一個讀數是 64954,因此將 diff() 分組當天的第一個和最后一個里程表值,有些公里正在消失,如下圖

def grp_odo(dfObj):
    dfObj['ODOMETER'] = dfObj['ODOMETER'].astype(int)
    dfObj["km"] = dfObj.groupby(["DATE","VEH"])["ODOMETER"].diff()

    sum_km = dfObj.groupby(["DATE","VEH"], as_index=False)["km"].sum()

    return sum_km

dfodo = grp_odo(df[['DATE','VEH', 'ODOMETER']].loc[(~pd.isna(df['ODOMETER']))])

打印每天的 groupby 里程表差異:

print(dfodo)

            DATE WSTRPVID     km
0     2021-01-01      001  523.0
1     2021-01-01      002  700.0
2     2021-01-01      003  781.0
3     2021-01-01      004    2.0
4     2021-01-01      005  553.0
...          ...      ...    ...
3375  2021-04-09      034  802.0
3376  2021-04-09      035  615.0
3377  2021-04-09      036  778.0
3378  2021-04-09      038  425.0
3379  2021-04-09      039  386.0

打印分組數據從開始到結束的總公里數。

print(dfodo[dfodo.VEH== "002"].sum())
km: 36796

打印 dataframe 中最高和最低里程表值的總和

print(df[df.VEH== "002"].groupby('VEH')['ODOMETER'].agg(np.ptp))

VEH
002    36898
Name: ODOMETER, dtype: int64

我想要一個 output,其中 2021-03-12 是 701km,所以 2021-03-12 的第一個值和 2021-03-13 的第一個值之間的差異,這可能嗎?

輸入:

>>> df
                       TS       DATE  VEH  ODOMETER
0 2021-03-12 12:58:15.500 2021-03-12  008    2932.0
1 2021-03-12 00:00:21.700 2021-03-12  002   64253.0
2 2021-03-12 00:02:21.500 2021-03-12  002   64254.0
3 2021-03-12 00:03:41.400 2021-03-12  002   64255.0
4 2021-03-12 00:05:38.200 2021-03-12  002   64256.0
5 2021-03-12 23:55:48.100 2021-03-12  002   64953.0
6 2021-03-12 00:05:38.200 2021-03-13  002   64954.0

Output:

>>> df.assign(TOTAL=df.groupby("VEH")["ODOMETER"].shift(-1) - df["ODOMETER"]) \ 
      .groupby(["DATE", "VEH"]).sum()["TOTAL"]
DATE        VEH
2021-03-12  002    701.0
            008      0.0
2021-03-13  002      0.0
Name: TOTAL, dtype: float64
df = pd.DataFrame({'DATE': ['2021-03-12', '2021-03-12', '2021-03-12', '2021-03-12', '2021-03-12', '2021-03-12', '2021-03-13'],
                  'VEH': ['008', '002', '002', '002', '002', '002', '002',],
                  'ODOMETER': [2932, 64253, 64254, 64255, 64256, 64953, 64954]})

df.sort_values(['VEH', 'DATE'], inplace=True)


         DATE  VEH  ODOMETER
1  2021-03-12  002     64253
2  2021-03-12  002     64254
3  2021-03-12  002     64255
4  2021-03-12  002     64256
5  2021-03-12  002     64953
6  2021-03-13  002     64954
0  2021-03-12  008      2932

為每個車輛、日期組創建一個采用最小 ODOMETER 值的列

dff = df.groupby(['VEH', 'DATE'], as_index=False).agg({'ODOMETER': 'min'})

   VEH        DATE  ODOMETER
0  002  2021-03-12     64253
1  002  2021-03-13     64954
2  008  2021-03-12      2932

車輛組的每個日期之間的差異。

dff['TOTAL_DIST'] = dff.groupby('VEH')['ODOMETER'].shift(-1)-dff.groupby('VEH')['ODOMETER'].shift(0)

   VEH        DATE  ODOMETER  TOTAL_DIST
0  002  2021-03-12     64253       701.0
1  002  2021-03-13     64954         NaN
2  008  2021-03-12      2932         NaN

您可以將 2 個連續的df.groupby()GroupBy.first()shift() ) 一起使用,如下所示:

df_daily = df.groupby(['DATE', 'VEH'], as_index=False)['ODOMETER'].first()
df_daily['km_diff'] = df_daily.groupby('VEH')['ODOMETER'].shift(-1) - df_daily.groupby('VEH')['ODOMETER'].shift(0)

測試運行

測試數據構建

cols= ['TS', 'DATE', 'VEH', 'ODOMETER']
data = [
['2021-03-12 12:58:15.500', '2021-03-12', '008'              , 2932],
['2021-03-13 12:58:15.500', '2021-03-13', '008'              , 3032],
['2021-03-12 00:00:21.700',     '2021-03-12',         '002',    64253],
['2021-03-12 00:02:21.500',     '2021-03-12',         '002', 64254],
['2021-03-12 00:03:41.400',     '2021-03-12',         '002',             64255],
['2021-03-12 00:05:38.200',     '2021-03-12',         '002',             64256],
['2021-03-12 23:55:88.100',     '2021-03-12',         '002',             64953],
['2021-03-12 00:05:38.200',     '2021-03-13',         '002',             64954]
]
df = pd.DataFrame(data, columns=cols)
print(df)


                        TS        DATE  VEH  ODOMETER
0  2021-03-12 12:58:15.500  2021-03-12  008      2932
1  2021-03-13 12:58:15.500  2021-03-13  008      3032       <=== Added this test data
2  2021-03-12 00:00:21.700  2021-03-12  002     64253
3  2021-03-12 00:02:21.500  2021-03-12  002     64254
4  2021-03-12 00:03:41.400  2021-03-12  002     64255
5  2021-03-12 00:05:38.200  2021-03-12  002     64256
6  2021-03-12 23:55:88.100  2021-03-12  002     64953
7  2021-03-12 00:05:38.200  2021-03-13  002     64954

運行新代碼

df_daily = df.groupby(['DATE', 'VEH'], as_index=False)['ODOMETER'].first()
df_daily['km_diff'] = df_daily.groupby('VEH')['ODOMETER'].shift(-1) - df_daily.groupby('VEH')['ODOMETER'].shift(0)

結果:

print(df_daily)



         DATE  VEH  ODOMETER  km_diff
0  2021-03-12  002     64253    701.0
1  2021-03-12  008      2932    100.0
2  2021-03-13  002     64954      NaN
3  2021-03-13  008      3032      NaN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM