Как drop_duplicate, используя разные условия для группы?
У меня есть dataFrame, и мне нужно удалить дубликаты на группу ('col1') на основе минимального значения в другом столбце 'abs(col1 - col2)', но мне нужно изменить это условие для последней группы, приняв максимальное значение в "abs (col1 - col2)", что соответствует последней группе в "col1", где я отсортировал "col1" в порядке возрастания. (вести себя как петля)
Обновление 1:
Мне нужно назначить последнюю группу динамически.
например, если у меня есть фрейм данных как
- создание DataFrame
df = pd.DataFrame( {'col0':['A','A','A','A','A','A','A','A','A','A','A','A','B','B','B','B','B','B','B','B','B','B','B','B'],'col1':[1,1,1,2,2,2,3,3,3,4,4,4,2,2,2,3,3,3,4,4,4,5,5,5], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3,3,4,5,2,4,5,2,3,5,2,3,4]})
вычислить столбец Diff (этот столбец будет использоваться как условие)
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
- Оригинальный Df следующим образом:
- Желаемый Df должен выглядеть так:
мое испытание:
df.sort_values(by=['col0','col1','abs(col1 - col2)','col2'],ascending=[True,True,True,False]).drop_duplicates(['col0','col1'])
В результате, как следует:
2 ответа
Обновлено:
Если я правильно понимаю, вы хотите, чтобы каждый порядок сортировки каждый раз, когда вы достигаете максимума на col1
,
- Извлеките группы, где сортировка отличается:
df.groupby(['col0'], as_index=False)['col1'].max()
- Дедуплицировать
df
как ты - Дублируйте только группы, найденные на шаге 1, с правильной сортировкой. Вы можете получить эти группы путем слияния с оригиналом
df
:
pd.merge(df, col1_max_groups)
- Обновить дедуплицированный
DataFrame
с новыми ценностями
Полный пример:
col1_max_groups = df.groupby(['col0'], as_index=False)['col1'].max()
deduped = df.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, True, False]) \
.drop_duplicates(['col0', 'col1']) \
.set_index(['col0', 'col1'])
update = pd.merge(df, col1_max_groups) \
.sort_values(['col0', 'col1', 'abs(col1 - col2)', 'col2'],
ascending=[True, True, False, False]) \
.drop_duplicates(['col0', 'col1'])
deduped.update(update.set_index(['col0', 'col1']))
deduped.reset_index()
# returns
# col0 col1 col2 abs(col1 - col2)
# A 1 2 1
# A 2 3 1
# A 3 4 1
# A 4 1 3
# B 2 3 1
# B 3 4 1
# B 4 5 1
# B 5 2 3
Если вы хотите получить именно этот конкретный результат, вы можете разделить фрейм данных и использовать два разных правила, а затем объединить их снова. Как пример:
import pandas as pd
df = pd.DataFrame( {'col1':[1,1,1,2,2,2,3,3,3,4,4,4], 'col2':[2,3,4,1,3,4,1,2,4,1,2,3]})
df['abs(col1 - col2)']=abs(df['col1']-df['col2'])
df = df.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False]).drop_duplicates('col1')
df1 = df.loc[df['col1'] != 4]
df2 = df.loc[df['col1'] == 4]
df2 = df2.sort_values(by=['col1','abs(col1 - col2)','col2'],ascending=[True,True,False])
df2Last = df2.tail(1)
df = pd.concat([df1, df2Last])
результат:
col1 col2 abs(col1 - col2)
1 2 1
2 3 1
3 4 1
4 1 3