根据列对日期中的日期排序,并使用Pandas保持其他列的值

时间:2019-04-12 15:44:34

标签: python pandas dataframe

我有一个像这样的数据集(这里的额外意思是多个额外的列)

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

我想在每个列id_police中排序日期(例如,2017年然后是2018年……),同样,我必须在每个重复的dateeffedate_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 个答案:

答案 0 :(得分:4)

使用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 :(得分:1)

我想出了一个基于两步分组方式的解决方案。

为了方便按groupby中的日期排序,让我们开始 将两个日期的类型都更改为datetime

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

第二部分是 Wen-Ben 的解决方案副本,用于创建字典 聚合功能(一种智能解决方案,无需任何其他方式):

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)产生一个带有 以下多索引:

id_police  
p123      0
          1
          2
b123      0

因此第一个reset_index会完全删除第1级( 0 1 2 0 ) (drop=True

但是第二个reset_index实际上改变了其余的 将索引级别( p123 p123 p123 b123 )划分为常规列, 创建默认索引(连续的数字从0开始)。