Добавить флаги в DataFrame на основе (сгруппированных) условий - PullRequest
1 голос
/ 21 октября 2019

Я работаю с пандой DataFrame, имеющей следующую структуру:

df1 = pd.DataFrame({'left_name' : ['left_name1', 'left_name2', 'left_name3', 'left_name4', 'left_name5', 'right_name6', 'right_name7', 'right_name8'], 
                    'right_name' : ['right_name1', 'right_name2', 'right_name2', 'right_name2', 'right_name3', 'right_name4', 'right_name4', 'right_name5'], 
                    'score' : [0.98, 0.99, 0.97, 0.91, 1, 0.92, 0.90, 0.96]})

print(df1)

     left_name   right_name  score
0   left_name1  right_name1   0.98
1   left_name2  right_name2   0.99
2   left_name3  right_name2   0.97
3   left_name4  right_name2   0.91
4   left_name5  right_name3   1.00
5  right_name6  right_name4   0.92
6  right_name7  right_name4   0.90
7  right_name8  right_name5   0.96

Я хотел бы добавить две новые колонки в таблицу выше. Визуально результирующий DataFrame должен выглядеть следующим образом:

     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

Правила для создания двух новых столбцов следующие:

  • Для col1 Серия: уникальная right_name s установлены на MATCH, а дубликаты right_name s установлены на POTENTIAL.
  • Для серии col2:
    • MATCH es помечены 1;
    • POTENTIAL s с наивысшими оценками помечены как 1 для каждой группы right_name (остальные отображаются на 0);

Мне трудно переводить вышеуказанные правила в код Python / Pandas. Любая помощь о том, как думать и кодировать это будет оценено.

1 Ответ

1 голос
/ 21 октября 2019

Решение, если необходимо сопоставить максимальное значение для групп - если существует 1 значение для групп и равно max, затем выберите его:

m = df1.groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col2'] = np.where(m, 1, 0)
print (df1)
     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

Или удалите все 1 строки, получитемаксимум для групп с добавлением 1 строк с | для побитового OR:

m = (df1[df1['score'].ne(1)]
       .groupby('right_name')['score'].transform('max')
       .eq(df1['score']).astype(int))

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col2'] = np.where(m | df1['score'].eq(1), 1, 0)
print (df1)
     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

Проверка разницы в измененных данных выборки:

df1 = pd.DataFrame({'left_name' : ['left_name1', 'left_name2', 'left_name3', 'left_name4', 'left_name5', 'right_name6', 'right_name7', 'right_name8'], 
                    'right_name' : ['right_name1', 'right_name2', 'right_name2', 'right_name2', 'right_name3', 'right_name4', 'right_name4', 'right_name5'], 
                    'score' : [0.98, 0.99, 0.97, 0.91, 1, 1.00, 0.90, 0.96]})

#print(df1)


m1 = df1.groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)
m2 = df1[df1['score'].ne(1)].groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col21'] = np.where(m, 1, 0)
df1['col22'] = np.where(m2 | df1['score'].eq(1), 1, 0)
print (df1)
     left_name   right_name  score       col1  col21  col22
0   left_name1  right_name1   0.98      MATCH      1      1
1   left_name2  right_name2   0.99  POTENTIAL      1      1
2   left_name3  right_name2   0.97  POTENTIAL      0      0
3   left_name4  right_name2   0.91  POTENTIAL      0      0
4   left_name5  right_name3   1.00      MATCH      0      1
5  right_name6  right_name4   1.00  POTENTIAL      1      1
6  right_name7  right_name4   0.90  POTENTIAL      0      1
7  right_name8  right_name5   0.96      MATCH      1      1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...