Создайте несколько логических столбцов в фрейме данных pandas на основе нескольких условий

#python #pandas #boolean

#питон #панды #логический

Вопрос:

У меня есть набор данных, в котором авторы ранжируются по порядку авторства (1, 2, 3 и т. Д.).

 Authorid Author Article Articleid Rank 1 John article 1 1 1 1 John article 2 2 2 1 John article 3 3 3 1 John article 4 4 3 2 Mary article 5 5 1 2 Mary article 6 6 2 2 Mary article 7 7 1 2 Mary article 8 8 8  

Я хочу создать еще три логических столбца If_first , If_second , If_last . Цель этого — я хочу показать, занимает ли автор 1, 2 или последнее место в статье. Это last означает максимальное число в Rank столбце (максимальное число для этого Authorid в столбце Rank ).

Я могу это сделать If_first , и If_second это довольно легко, но не знаю, как решить If_last .

 df.loc[df['Rank'] == 1, 'If_first'] = 1 df.loc[df['Rank'] != 1, 'If_first'] = 0 df.loc[df['Rank'] == 2, 'If_second'] = 1 df.loc[df['Rank'] != 2, 'If_second'] = 0  

Здесь два правила

  • If_first = if_last — относитесь к нему как if_first
  • If_second = if_last — относитесь к нему как if_second

Ожидаемый результат:

 Authorid Author Article Articleid Rank If_first If_second If_last 1 John article 1 1 1 1 0 0 1 John article 2 2 2 0 1 0 1 John article 3 3 3 0 0 1 (third is the last here) 2 Mary article 5 5 1 1 0 0 2 Mary article 6 6 2 0 1 0 2 Mary article 7 7 3 0 0 0 (third is not the last here, because of the fourth below, all zeros) 2 Mary article 8 8 4 0 0 1 (fourth is the last here)  

Комментарии:

1. Есть ли дополнительная строка в образцах данных? Последний в Authorid == 1? Его нет в ваших выходных данных. Или нам нужно удалить одну из строк, если в одном и том же идентификаторе есть строки с одинаковым рангом?

2. @sophocles, я снова обновил вывод. Если автор 1,2,3 не последний — тогда все значения должны быть равны нулю. Каким-то образом мне нужно вычислить, каков максимальный ранг x для каждого идентификатора автора, и назначить его последним. Надеюсь, это поможет!

Ответ №1:

Попробуйте это:

 df = df.reset_index(drop=True) res = df.groupby('Authorid')['Rank'].apply(lambda x: [x.idxmin(), x.drop_duplicates()[1:].nsmallest(1).index[0], x.idxmax()])  df[['If_first', 'If_second', 'If_last']] = 0 df.loc[res.str[0].tolist(), 'If_first'] = 1 df.loc[res.str[1].tolist(), 'If_second'] = 1 df.loc[res.str[2].tolist(), 'If_last'] = 1  

Выход:

 gt;gt;gt; df  Authorid Author Article Articleid Rank If_first If_second If_last 0 John article 1 1 1 1 0 0 1 John article 2 2 2 0 1 0 2 John article 3 3 3 0 0 1 3 John article 4 4 3 0 0 0 4 Mary article 5 5 1 1 0 0 5 Mary article 6 6 2 0 1 0 6 Mary article 7 7 1 0 0 0 7 Mary article 8 8 8 0 0 1  

Ответ №2:

Одним из подходов может быть создание второго кадра данных, сгруппированного путем Articleid сбора интересующей вас статистики:

 df2 = df.groupby('Articleid').agg(mxrank=('Rank', 'max'))  

затем добавьте новый столбец, объединив фреймы данных:

 dfm = df.merge(df2, how='left', on='Articleid')  

С примером результата (с некоторыми добавленными строками для демонстрации статьи «article4» с несколькими рангами):

 Authorid Author Article Articleid Rank mxrank 0 1 John article1 1 1 1 1 1 John article2 2 2 2 2 1 John article3 3 3 3 3 1 John article4 4 3 4 4 1 Foo article4 4 1 4 5 1 Bar article4 4 2 4 6 1 Baz article4 4 4 4 7 2 Mary article5 5 1 1 8 2 Mary article6 6 2 2 9 2 Mary article7 7 1 1 10 2 Mary article8 8 8 8  

Затем сравните mxrank столбец с Rank , чтобы определить флаг для каждой строки.