在 Pandas/Dask 数据框中标记最后日期记录

Mark last date record in Pandas/Dask dataframes

在下面的 Dask 数据集中,我有一个 ID 列表(例如 12)和日期(最后一列)。

我需要向数据框添加一个新列,如果日期是该 ID 的最后一个,则该列将具有 1。例如,对于 id 2,最后日期是 2021-05-01。如果不是最后一个,则该列应为 None 或 0.

整个集合按 ID 和日期排序,以备不时之需。

我曾经用 SQL 来做到这一点,在 where 子句中有 where NOT EXISTS date > (select max(date)) ...

Pandas and/or Dask 可以吗?

  pdf = pd.DataFrame({
        'id': [1, 1, 1, 2, 2],
        'balance': [150, 140, 130, 280, 260],
        'date' : ['2021-03-01', '2021-04-01', '2021-05-01', '2021-01-01', '2021-02-01']
    })
    print(pdf)

    id  balance        date
0   1      150  2021-03-01
1   1      140  2021-04-01
2   1      130  2021-05-01
3   2      280  2021-04-01
4   2      260  2021-05-01

pdf['date2'] = pd.to_datetime(pdf['date'])
ddf = dd.from_pandas(pdf, npartitions=1) 
ddf.compute()

id  balance    date      date2
0   1   150 2021-03-01  2021-03-01
1   1   140 2021-04-01  2021-04-01
2   1   130 2021-05-01  2021-05-01
3   2   280 2021-04-01  2021-04-01
4   2   260 2021-05-01  2021-05-01

例如最终结果将是

id  balance    date      date2      last_date_flag
0   1   150 2021-03-01  2021-03-01    0
1   1   140 2021-04-01  2021-04-01    0
2   1   130 2021-05-01  2021-05-01    1
3   2   280 2021-04-01  2021-04-01    0
4   2   260 2021-05-01  2021-05-01    1

这是我将用于 pandas 的方法,不确定 Dask。

pdf['last_date_flag'] = pdf.groupby('id')['date'].transform(lambda x: x == x.max()).astype(int)

给予


id  balance date    date2   last_date_flag
0   1   150 2021-03-01  2021-03-01  0
1   1   140 2021-04-01  2021-04-01  0
2   1   130 2021-05-01  2021-05-01  1
3   2   280 2021-01-01  2021-01-01  0
4   2   260 2021-02-01  2021-02-01  1

如果您关心可伸缩性,这在大型数据集上执行得更快:


pdf['last_date_flag'] = (pdf['date'] == pdf['id'].map(pdf.groupby('id')['date'].max().to_dict())).astype(int)
pdf['date'] = pd.to_datetime(pdf['date'])
pdf['last_date_flag']=(pdf.groupby('id')['date'].transform(lambda x:x.max()).eq(pdf['date'])).astype(int)


    id  balance       date  last_date_flag
0   1      150 2021-03-01               0
1   1      140 2021-04-01               0
2   1      130 2021-05-01               1
3   2      280 2021-04-01               0
4   2      260 2021-05-01               1