Сортировать даты в DataFrame по столбцу, сохраняя значения других столбцов, используя Pandas - PullRequest
3 голосов
/ 12 апреля 2019

У меня есть такой набор данных (здесь дополнительный означает несколько дополнительных столбцов) :

>>> df = pd.DataFrame({'id_police':['p123','p123','p123','b123','b123'],
                   'dateeffe':['24/01/2018','24/11/2017','25/02/2018','24/02/2018','24/02/2018'],
                   'date_fin':['23/03/2018','23/12/2017','26/03/2018','25/02/2018','25/02/2018'],
                   'prime':[0,20,10,20,30],
                   'prime2':[0,30,10,20,0],
                   'extra':[12,12,13,15,20],
                   ...
})
###
  id_police    dateeffe    date_fin  prime  prime2  extra  ...
0      p123  24/01/2018  23/03/2018      0       0     12  ...
1      p123  24/11/2017  23/12/2017     20      30     12  ...
2      p123  25/02/2018  26/03/2018     10      10     13  ...
3      b123  24/02/2018  25/02/2018     20      20     15  ...
4      b123  24/02/2018  25/02/2018     30       0     20  ...

Я хочу отсортировать даты (например, 2017, затем 2018 ...) в каждом столбцеid_police также мне придется сохранять максимальное простое число в каждом дубликате dateeffe и date_fin, как в 3 и 4, имеющих одинаковые id_police.

Это ожидаемый результат:

  id_police    dateeffe    date_fin  prime  prime2  extra  ...
0      p123  24/11/2017  23/12/2017     20      30     12  ...
1      p123  24/01/2018  23/03/2018      0       0     12  ...
2      p123  25/02/2018  26/03/2018     10      10     13  ...
3      b123  24/02/2018  25/02/2018     30      20     15  ...

Чтобы найти максимальное простое и простое2, я использовал это:

df = df.groupby(['id_police','dateeffe','date_fin'],as_index=False).agg({'prime':'max','prime2':'max'})

Это то, что я пытался, но он группирует все, и я теряю столбец дополнительно ...

df1 = df.sort_values(['dateeffe','date_fin']).groupby('id_police', as_index=False).apply(lambda x: x) 

Я посмотрел везде, и я ценю вашу помощь, спасибо заранее!

Ответы [ 2 ]

4 голосов
/ 12 апреля 2019

Проверьте выход с помощью first

df = df.groupby(['id_police','dateeffe','date_fin'],as_index=False).agg({'prime':'max','prime2':'max','extra':'first'})
df
Out[482]: 
  id_police    dateeffe    date_fin  prime  prime2  extra
0      b123  24/02/2018  25/02/2018     30      20     15
1      p123  24/01/2018  23/03/2018      0       0     12
2      p123  24/11/2017  23/12/2017     20      30     12
3      p123  25/02/2018  26/03/2018     10      10     13

Обновление

d={'prime':'max','prime2':'max'}
d1=dict.fromkeys(df.columns.difference(['id_police','dateeffe','date_fin','prime','prime2']),'first')
d.update(d1)
df=df.groupby(['id_police','dateeffe','date_fin'],as_index=False).agg(d)
Out[501]: 
  id_police    dateeffe    date_fin  prime  prime2  extra
0      b123  24/02/2018  25/02/2018     30      20     15
1      p123  24/01/2018  23/03/2018      0       0     12
2      p123  24/11/2017  23/12/2017     20      30     12
3      p123  25/02/2018  26/03/2018     10      10     13
df.dateeffe=pd.to_datetime(df.dateeffe)
df.date_fin=pd.to_datetime(df.date_fin)
df=df.sort_values(['id_police','dateeffe','date_fin'])
1 голос
/ 12 апреля 2019

Я придумал решение, основанное на двухступенчатой ​​групповой операции .

Чтобы упростить сортировку по датам в groupby, давайте начнем с изменения типа обеих дат на datetime:

df.dateeffe = pd.to_datetime(df.dateeffe)
df.date_fin = pd.to_datetime(df.date_fin)

Вторая часть представляет собой копию решения Вэнь-Бена , предназначенного для создания словаря функций агрегации (умное решение, не нужно ничего делатьДругой способ):

d = {'prime': 'max', 'prime2': 'max'}
d1 = dict.fromkeys(df.columns.difference(
    ['id_police', 'dateeffe', 'date_fin', 'prime', 'prime2']), 'first')
d.update(d1)

Тогда давайте определим функцию, содержащую второй шаг groupby, применяя вышеупомянутые функции агрегирования:

def fn(xx):
    return xx.groupby(['dateeffe', 'date_fin'], as_index=False).agg(d)

И единственное, что нужно сделать, этофактическое вычисление, т.е. первый шаг groupby с применением второго шага groupby, определенного выше:

df.groupby('id_police', sort=False).apply(fn)\
    .reset_index(level=1, drop=True).reset_index()

Обратите внимание на разницу между обоими groupby случаями:

  • Первый шаг groupby содержит sort=False, поэтому сохраняется первоначальный порядок id_police.
  • Но второй шаг groupby не имеет аргумента sort, поэтому эта группировка выполняетсядля сортировки в обе даты.

И немного пояснений относительно обоих вызовов reset_index:

df.groupby('id_police', sort=False).apply(fn) создает DataFrame со следующим мультииндексом:

id_police  
p123      0
          1
          2
b123      0

Таким образом, первый reset_index полностью удаляет уровень 1 ( 0 , 1 , 2 , 0 ) (drop=True).

Но второй reset_index фактически изменяет только оставшийся уровень индекса (* 1058)* p123 , p123 , p123 , b123 ) в обычный столбец и создает индекс по умолчанию (последовательные числа от 0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...