Панды: медиана столбца, сгруппированного по другим столбцам

2020-08-01 python pandas pandas-groupby

У меня есть датафрейм как таковой

 plan_id route_id   dtn
   801      12289     2629.0
   801      12289     1666.0
   801      12289     7700.0
   801      12289     2216.0
   801      7734      2219.0
   801      7734      853.0
   653      8819      3375.0
   653      8819      2184.0

dtn в секундах. а dtn - это расстояние до следующей доставки в маршруте, т. е. при индексе 3 это будет расстояние между индексом доставки 3 и индексом доставки 4. **

Мне нужно найти среднее расстояние, пройденное для каждого route_id для данного plan_id, и добавить его в виде столбца в существующий фрейм данных, сопоставленный с соответствующими pid и route_id.

Сначала я суммировал dtn, чтобы найти общее расстояние, пройденное по маршруту (route_id) и plan_id, используя

df=df.groupby(['plan_id','route_id'])['dtn'].sum().reset_index()

Затем я решил сгруппировать еще раз, используя plan_id и route_id, чтобы получить медианное значение, используя

df.groupby(['plan_id','route_id')['dtn'].median()

Однако он возвращает тот же суммарный кадр данных без каких-либо изменений. Стоит отметить, что plain_id может иметь несколько маршрутов (route_id) и наоборот.

Answers

Если вы ищете медианное значение для данного идентификатора плана и rout_id, почему вы используете сумму? используя представленный вами df:

df=pd.DataFrame({
"plan_id":[801,801,801,801,801,801,653,653],
"route_id": [12289,12289,12289,12289,7734,7734,8819,8819],
"dtn":[2629,1666,7700,2216,2219,853,3375,2184]})

Я изменил столбец dtn на маленькие числа, чтобы было легче понять медиану:

df["dtn"]=range(1,9)
df
    plan_id route_id    dtn
  0  801    12289       1
  1  801    12289       2
  2  801    12289       3
  3  801    12289       4
  4  801    7734        5
  5  801    7734        6
  6  653    8819        7
  7  653    8819        8

Из этого примера вы можете видеть, что медиана pid 801 для данного route_id 12289 является медианной для этой группы чисел: [1,2,3,4]. значение 2,5

Медиана pid 801 и идентификатора маршрута 7734 - это медиана [5,6], то есть 5,5 и т. д.

результат можно получить с помощью:

    grouped=df.groupby(['plan_id','route_id'])['dtn'].median().reset_index()
    grouped
    plan_id route_id    dtn
    0   653 8819        7.5
    1   801 7734        5.5
    2   801 12289       2.5

теперь вы можете объединить свой df с сгруппированным, чтобы получить медианное значение для каждого pid и идентификатора маршрута в виде столбца

df.merge(grouped, left_on=['plan_id','route_id'],right_on= 
['plan_id','route_id'],suffixes=("","_median"))
    plan_id route_id    dtn dtn_median
  0  801    12289          1    2.5
  1  801    12289          2    2.5
  2  801    12289          3    2.5
  3  801    12289          4    2.5
  4  801    7734           5    5.5
  5  801    7734           6    5.5
  6  653    8819           7    7.5
  7  653    8819           8    7.5

Related