#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