Python, Pandas: Отбросьте столбцы фрейма данных и объедините строки с условием

#python #pandas #dataframe

Вопрос:

У меня есть фрейм данных, похожий на этот:

Оригинал

 # | col_a | col_b | .. 1 | 100725 | No | .. 2 | 100726 | Yes | .. 3 | 100726 | No | .. 4 | 100726 | No | .. 5 | 100727 | Yes | .. 6 | 100728 | No | .. 7 | 100728 | Yes | .. 8 | 100728 | Yes | .. 9 | 100729 | No | .. 10 | 100729 | No | ..  

Результат

 # | col_a | col_b | .. 1 | 100725 | No | .. 2 | 100726 | Yes | .. 5 | 100727 | Yes | .. 8 | 100728 | Yes | .. 9 | 100729 | No | ..  

Чего я пытаюсь достичь: как показано выше, я хочу создать новый фрейм данных только с уникальными номерами внутри col_a, но с изюминкой: в col_b я хочу получить «Да«, независимо от того, содержит ли все или только одна строка это значение. Только если есть только значения «Нет«, я хочу получить » Нет » в конечном кадре данных.

Есть ли разумный способ создать такой фрейм данных без создания множества временных столбцов для вычисления.

Спасибо за вашу помощь и хорошего дня!

прекрасно, когда

Ответ №1:

Отсортируйте col_b значения (сначала «Да», затем «Нет»), затем сохраните первое вхождение col_b и, наконец, восстановите порядок индекса:

 gt;gt;gt; df.sort_values('col_b', ascending=False).drop_duplicates('col_a').sort_index()   col_a col_b 0 100725 No 1 100726 Yes 4 100727 Yes 6 100728 Yes 8 100729 No  

Шаг за шагом:

 gt;gt;gt; df.sort_values('col_b', ascending=False)  col_a col_b 1 100726 Yes 4 100727 Yes 6 100728 Yes 7 100728 Yes 0 100725 No 2 100726 No 3 100726 No 5 100728 No 8 100729 No 9 100729 No  gt;gt;gt; df.sort_values('col_b', ascending=False).drop_duplicates('col_a')  col_a col_b 1 100726 Yes 4 100727 Yes 6 100728 Yes 0 100725 No 8 100729 No  gt;gt;gt; df.sort_values('col_b', ascending=False).drop_duplicates('col_a').sort_index()  col_a col_b 0 100725 No 1 100726 Yes 4 100727 Yes 6 100728 Yes 8 100729 No  

Установка:

 data = {'col_a': [100725, 100726, 100726, 100726, 100727,  100728, 100728, 100728, 100729, 100729],  'col_b': ['No', 'Yes', 'No', 'No', 'Yes', 'No', 'Yes', 'Yes', 'No', 'No']} df = pd.DataFrame(data) print(df)  # Output:  col_a col_b 0 100725 No 1 100726 Yes 2 100726 No 3 100726 No 4 100727 Yes 5 100728 No 6 100728 Yes 7 100728 Yes 8 100729 No 9 100729 No  

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

1. Спасибо! Намного лучше, чем то, что я придумал…

Ответ №2:

groupby, где есть какие-либо Да, транслируйте их, а затем отбросьте дублированные.

 df=df.assign(col_b=np.where(df.groupby('col_a')['col_b'].transform(lambda x:( x=='Yes').any()),'Yes', df['col_b'])).drop_duplicates(subset=['col_a','col_b'], keep='first')  print(df)    # col_a col_b 0 1 100725 No 1 2 100726 Yes 4 5 100727 Yes 5 6 100728 Yes 8 9 100729 No