Как 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,

  1. Извлеките группы, где сортировка отличается:
df.groupby(['col0'], as_index=False)['col1'].max()
  1. Дедуплицировать df как ты
  2. Дублируйте только группы, найденные на шаге 1, с правильной сортировкой. Вы можете получить эти группы путем слияния с оригиналом df:
pd.merge(df, col1_max_groups)
  1. Обновить дедуплицированный 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
Другие вопросы по тегам