Панды: ранг за групповым, используя минранк - PullRequest
1 голос
/ 24 апреля 2019

Я знаю, что метод rank существует в pandas.DataFrame.groupby, но мне было интересно, могу ли я использовать метод min rank, чтобы получить тот же результат, что и в языке программирования R дляследующая проблема.

Набор данных, скопированный на мой github, составляет несколько МБ.

Моя попытка:

import numpy as np
import pandas as pd

flights = pd.read_csv('https://github.com/bhishanpdl/Datasets/blob/master/nycflights13.csv?raw=true')
print(flights.shape)


df = (flights[flights.tailnum.notna()]
      .assign( on_time = lambda x: x.arr_time.notna() & (x.arr_delay <=0))
      .groupby('tailnum')['on_time']
      .agg([np.mean,'count',pd.Series.rank(method='min')]) # R uses min_rank
      .set_axis(['on_time','n','rank'],axis=1,inplace=False)
      .query( 'rank == 1.0')
     )

df.head()

Выдает ошибку.

Обязательный вывод

shape= 336776, 19

HEAD
tailnum on_time n
N121DE  0   2
N136DL  0   1
N143DA  0   1
N17627  0   2
N240AT  0   5
N26906  0   1

TAIL
tailnum on_time n
N939DN  0   1
N943DN  0   1
N953FR  0   3
N960DN  0   3
N965DN  0   2
N978SW  0   1

Код R работает отлично, но я хочу использовать Pandas

library(tidyverse)
library(nycflights13)
library(dplyr)

df = flights %>%
  filter(!is.na(tailnum)) %>%
  mutate(on_time = !is.na(arr_time) & (arr_delay <= 0)) %>%
  group_by(tailnum) %>%
  summarise(on_time = mean(on_time), n = n()) %>%
  filter(min_rank(on_time) == 1)


dim(flights)
head(df)
tail(df)

Помощь приветствуется.

Ссылки по теме:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.GroupBy.rank.html

1 Ответ

1 голос
/ 24 апреля 2019

В dplyr R min_rank - это не агрегированная функция, а вычисление после агрегирования (на самом деле основано на оконной функции ANSI SQL 2003, RANK () OVER (), которая также не агрегатная функция). Поэтому добавьте такой вычисляемый столбец во фрейм данных Pandas после агрегации , а не внутри agg(). Затем вызовите reindex или drop, чтобы исключить вспомогательный столбец:

df = (flights[flights.tailnum.notna()]
      .assign( on_time = lambda x: x.arr_time.notna() & (x.arr_delay <=0))
      .groupby('tailnum')['on_time']
      .agg([np.mean, 'count'])
      .set_axis(['on_time','n'],axis=1, inplace=False)
      .assign(rank = lambda x: pd.Series.rank(x['on_time'], method='min'))
      .query("rank == 1") 
      .reindex(columns=['on_time', 'n']) # OR .drop(columns=['rank'])
     )

print(flights.shape)
# (336776, 19)

print(df.head())
#          on_time  n
# tailnum
# N121DE       0.0  2
# N136DL       0.0  1
# N143DA       0.0  1
# N17627       0.0  2
# N240AT       0.0  5

print(df.tail())
#          on_time  n
# tailnum
# N943DN       0.0  1
# N953FR       0.0  3
# N960DN       0.0  3
# N965DN       0.0  2
# N978SW       0.0  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...