Python Pandas:如何只采用每组中最早的日期

时间:2017-10-26 18:36:47

标签: python pandas

这是我为此问题创建的示例数据集:

data1 = pd.DataFrame([['1','303','3/7/2016'],
                     ['4','404','6/23/2011'],
                     ['7','101','3/7/2016'],
                     ['1','303','5/6/2017']],
                    columns=["code", "ticket #", "CB date"])
data1['CB date'] = pd.to_datetime(data1['CB date'])
data2 = pd.DataFrame([['1','303','2/5/2016'],
                     ['4','404','6/23/2011'],
                     ['7','101','3/17/2016'],
                     ['1','303','4/6/2017']],
                    columns=["code", "ticket #", "audit date"])
data2['audit date'] = pd.to_datetime(data2['audit date'])
print(data1)
print(data2)
  code ticket #    CB date
0    1      303 2016-03-07
1    4      404 2011-06-23
2    7      101 2016-03-07
3    1      303 2017-05-06
  code ticket # audit date
0    1      303 2016-02-05
1    4      404 2011-06-23
2    7      101 2016-03-17
3    1      303 2017-04-06

我想合并两个df,并确保CB日期始终在审核日期之前或之后:

data_all = data1.merge(data2, how='inner', on=['code', 'ticket #'])
data_all = data_all[data_all['audit date'] <= data_all['CB date']]
print(data_all)
  code ticket #    CB date audit date
0    1      303 2016-03-07 2016-02-05
2    1      303 2017-05-06 2016-02-05
3    1      303 2017-05-06 2017-04-06
4    4      404 2011-06-23 2011-06-23

但是,我只希望在每个审核日期之后保留最早的CB日期。所以在上面的输出中,第2行不应该存在,因为第1行和第2行都有相同的审核日期2016/2/5,但我只想保留第1行,因为CB日期更接近2016/2 / 5比第2行CB日期确实。

期望的输出:

code ticket #    CB date audit date
0    1      303 2016-03-07 2016-02-05
3    1      303 2017-05-06 2017-04-06
4    4      404 2011-06-23 2011-06-23

我知道在SQL中我必须使用gorupby代码&amp;门票#&amp;首先审核日期,然后按升序排序CB日期,然后在每个组中取项目rank = 1;但我怎么能在Python / Pandas中做到这一点?

我在这里阅读了其他帖子,但我仍然没有得到它,所以非常感谢这里的一些建议。

我读到的帖子很少包括:

  1. Pandas Groupy take only the first N Groups
  2. Pandas: select the first couple of rows in each group

1 个答案:

答案 0 :(得分:1)

我通过可选的sort_values来电和drop_duplicates来电来完成此操作。

data_all.sort_values(data_all.columns.tolist())\
          .drop_duplicates(subset=['CB date'], keep='first')
  code ticket #    CB date audit date
0    1      303 2016-03-07 2016-02-05
2    1      303 2017-05-06 2016-02-05
4    4      404 2011-06-23 2011-06-23

我说sort_values来电是可选的,因为您的数据似乎已经排序了。如果不是,请确保您的解决方案的一部分。