根据熊猫数据框中的其他两列设置列的值

数据挖掘 Python 熊猫 效率
2022-03-01 03:01:10

我有一个数据框,其中包含具有不同订单日期的合同,如果每个合同有多个订单日期,我需要创建一个新列,为每个合同分配一个数字。例如,我的示例数据框如下所示:

df = pd.DataFrame({'contract': ['123A','123A','123A','123A','123B','123B','123C'],'prod': ['X1','M1','V1','D1','A1','B1','C1'],'date':['2019-04-17','2019-07-02','2019-04-17','2019-07-02','2019-04-17','2019-09-01','2019-08-02'],'revenue': [5688,113932,5688,49157,5002,892,9000]})

我需要我的决赛桌有另一个列,每个日期都有一个唯一的合同 ID。我上面的决赛桌应该是这样的:

合同 日期 header_contract
123A 2019-04-17 123A_0
123A 2019-07-02 123A_1
123A 2019-04-17 123A_0
123A 2019-08-02 123A_2

我有以下代码可以在较小的数据集上完成我需要的操作:

contracts_num = df['contract'].unique()
for cm in contracts_num:
    for idx,val in enumerate(df[df['contract'] == cm]['contract'].dt.date.unique()):
        df.loc[((df['contract'] == cm) & (df['contract'] == str(val))),'contract'] = df['contract'] + '_' + str(idx)

我正在尝试在更大的数据集(大约 50,000 个合同)上进行此操作,并且需要很长时间。有没有办法让它更有效率?

1个回答

您可以与 和groupby一起使用shiftcumsum如下所示:

df['header_contract'] = df['contract'] + '_' + df.sort_values(['contract', 'date']).\
  groupby('contract')["date"].\
  apply(lambda x: (x.shift() != x).cumsum()).astype(str)

在 ,apply中,x.shift() != x用于创建一系列新的布尔值,对应于下一行中的日期是否已更改。cumsum然后将创建一个累积总和(将所有 True 视为 1),它为每个组创建后缀。然后将其与合同名称合并以创建新列。

结果:

  contract prod       date  revenue header_contract
0     123A   X1 2019-04-17     5688          123A_1
1     123A   M1 2019-07-02   113932          123A_2
2     123A   V1 2019-04-17     5688          123A_1
3     123A   D1 2019-07-02    49157          123A_2
4     123B   A1 2019-04-17     5002          123B_1
5     123B   B1 2019-09-01      892          123B_2
6     123C   C1 2019-08-02     9000          123C_1