Как рассчитать медиану для времени?

Исходные данные:

operation   date    user    duration_time
0   0   03.01.2018  30159   00:04:01
1   0   03.01.2018  30161   00:31:35
2   0   03.01.2018  30172   00:00:17
3   0   03.01.2018  38830   00:03:13
4   0   03.01.2018  38840   04:39:36
... ... ... ... ...
8975    9008    18.01.2018  39217   00:00:00
8976    9008    26.01.2018  38753   00:00:00
8977    9008    29.01.2018  30156   00:00:00
8978    9008    30.01.2018  39084   00:00:00
8979    9008    30.01.2018  39217   00:00:00

operation         int64
date             object
user              int64
duration_time    object
dtype: object

Мой код:

import pandas as pd
from datetime import datetime as dt

severstal_df = pd.read_csv('C:/Какой-то файл.csv', sep = ';', encoding = 'windows-1251')

severstal_df = severstal_df.rename(columns = {'Операция': 'operation', 
                               'Дата': 'date', 
                               'Время': 'time', 
                               'Пользов': 'user'})

severstal_df['duration'] = pd.to_datetime(severstal_df['time'], format = '%H:%M:%S')

severstal_df = severstal_df.groupby(['operation', 'date', 'user'])\
                           .duration.apply(lambda x: x.max() - x.min()).reset_index(name = 'duration')

severstal_df['duration_time'] = (pd.Timestamp('today').normalize() + severstal_df['duration']).dt.time

severstal_df['duration_median'] = severstal_df.groupby(['operation', 'date','user'])\
                                              ['duration_time'].median()
severstal_df

Ошибка:

DataError: No numeric types to aggregate

Как надо посчитать, чтобы не возникала ошибка?


Ответы (2 шт):

Автор решения: passant

"чтобы не вылезала ошибка" думаю надо бы написать вот так:

severstal_df['duration_median'] = severstal_df.groupby(['operation', 'date','user'])\
                                              ['duration_time'].median()

Только вот ввиду того, что 'duration_time' у вас скорее всего представлен как timedelta (о чем мы можем только гадать), так как воспроизводимого фрагмента кода вы не предоставили) - вы получите ошибку связанную с No numeric types. А раз воспроизводимого фрагмента кода вы не предоставили (как того требуют правила форума), то как из этой ситуации выкрутиться - решать теперь вам.

→ Ссылка
Автор решения: MaxU

исходный DataFrame:

In [111]: df
Out[111]:
   operation        date  user duration_time
0          0  03.01.2018     1      00:04:01
1          0  03.01.2018     1      00:31:35
2          0  03.01.2018     1      00:00:17
3          0  03.01.2018     2      00:03:13
4          0  03.01.2018     2      04:39:36
5          1  04.01.2018     1      01:02:03
6          1  04.01.2018     3      00:12:33

In [112]: df.dtypes
Out[112]:
operation         int64
date             object
user              int64
duration_time    object
dtype: object

решение:

def timedelta_to_str(td):
    h = f"{td.components.hours:02d}"
    m = f"{td.components.minutes:02d}"
    s = f"{td.components.seconds:02d}"
    return f"{h}:{m}:{s}"

df["duration_median"] = (
    df
    .groupby(["operation", "date", "user"])
    ['duration_time']
    .transform(lambda x: pd.to_timedelta(x).median())
    .map(timedelta_to_str)
)

результат:

In [114]: df
Out[114]:
   operation        date  user duration_time duration_median
0          0  03.01.2018     1      00:04:01        00:04:01
1          0  03.01.2018     1      00:31:35        00:04:01
2          0  03.01.2018     1      00:00:17        00:04:01
3          0  03.01.2018     2      00:03:13        02:21:24
4          0  03.01.2018     2      04:39:36        02:21:24
5          1  04.01.2018     1      01:02:03        01:02:03
6          1  04.01.2018     3      00:12:33        00:12:33
→ Ссылка