#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
, чтобы определить флаг для каждой строки.