Как drop_duplicate, используя разные условия для группы? - PullRequest
0 голосов
/ 28 марта 2019

У меня есть 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 следующим образом:

enter image description here

  • Требуемый Df долженвыглядит так:

enter image description here

  • мой тест:

    df.sort_values(by=['col0','col1','abs(col1 - col2)','col2'],ascending=[True,True,True,False]).drop_duplicates(['col0','col1'])

  • получено следующее:

enter image description here

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Обновлен:

Если я правильно понимаю, вам нужен каждый порядок сортировки каждый раз, когда вы достигаете максимума на 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
1 голос
/ 28 марта 2019

Если вы хотите получить именно этот конкретный результат, вы можете разделить фрейм данных и использовать два разных правила, а затем объединить их снова.Как пример:

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
...