Применение рангов к каждой группе в Pandas Groupby - PullRequest
1 голос
/ 07 апреля 2020

Скажем, у меня есть простой набор данных (а именно, df1), например:

 ID     Name     Max_FileID
--------------------------------
  1      Dog          3
  1      Dog          3
  1      Dog          3
  2      Bird         1
  3      Cat          5
  3      Cat          5

Я хотел бы сгруппировать набор данных по идентификатору (у меня нет проблем с этим):

df1.groupby('ID')

Затем добавьте новый столбец, используя Max_FileID + Rank.

Результат должен выглядеть следующим образом

 ID     Name     Max_FileID     Rank
------------------------------------------
  1      Dog          3           4
  1      Dog          3           5
  1      Dog          3           6
  2      Bird         1           2
  3      Cat          5           6
  3      Cat          5           7

Чтобы лучше понять, чего я пытаюсь достичь, вот эквивалент SQL:

SELECT
    ID,
    Name,
    Max_FileID,
    Max_FileID + ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID)
FROM df1

В Кроме того, я создал пользовательскую функцию:

def sequential_ranking(self, iterable, max_id):
  try:
    max_id = max_id - 1
    seq_nums = list()
    for num in iterable:
      max_id += 1
      seq_nums.append(max_id)
    return seq_nums

Не уверен, есть ли для нее встроенная функция. Заранее спасибо !!

Ответы [ 3 ]

1 голос
/ 07 апреля 2020

Вы можете использовать функцию DataFrameGroupBy.rank, которая возвращает значения рангов в группе, и если вы указываете параметр метода для first, то ранги присваиваются в порядке их появления в группе.

Вы можете использовать это:

df["Rank"] = df["Max_FileID"] + df.groupby("ID")["Max_FileID"].rank(method="first").astype(int)

Результат:

>>> print(df)

   ID  Name  Max_FileID  Rank
0   1   Dog           3     4
1   1   Dog           3     5
2   1   Dog           3     6
3   2  Bird           1     2
4   3   Cat           5     6
5   3   Cat           5     7
1 голос
/ 07 апреля 2020

Вы можете использовать groupby, затем применить пользовательское преобразование, добавив np.arange:

df['Rank'] = df.groupby('ID')['Max_FileID'].transform(lambda x: x+np.arange(1, len(x)+1))
0 голосов
/ 07 апреля 2020

Приведенный вами пример несколько сбивает с толку, когда вы сказали «затем добавьте новый столбец, используя Max_FileID + Rank», но в этом примере новый столбец называется «Rank», даже если он выглядит как сумма значений Rank и Max_FileID.

Я думаю, вам просто нужно использовать groupby().rank() Вы можете опустить промежуточный столбец рейтинга, если он не нужен.

df['rank'] = df.groupby('ID').rank(method='first').astype(int)
df['newcol'] = df['Max_FileID'] + df['rank']

Выход

df

=== Output: ===
   ID  Name  Max_FileID  rank  newcol
0   1   Dog           3     1       4
1   1   Dog           3     2       5
2   1   Dog           3     3       6
3   2  Bird           1     1       2
4   3   Cat           5     1       6
5   3   Cat           5     2       7
...