熊猫-在日期之前和之后的指定时间段内汇总值

时间:2019-05-21 19:00:04

标签: python pandas

我有一个名称和令牌表,其中每个名称都与一个唯一的令牌相关联,并且每个令牌有两个汇总成本。给出了使用令牌的日期。

    Token   Name  AggCost1  AggCost2        Date
0  token1  nameX        26        70  2019-01-01
1  token2  nameY       100       120  2018-11-11

从第一个表中的日期开始,我想在使用特定令牌之前的3个月的时间间隔内,对下面第二个表中出现在第一个表中的每个名称的Cost1和Cost2进行汇总(日期表示为-3mo)使用后的3个月(日期为+ 3mo)。在此表中,名称和令牌之间的关系是一对多的。

    Name        Date   Token  Cost1  Cost2
0  nameX  2018-10-03  tokenA      0     30
1  nameX  2018-12-12  tokenB     40     20
2  nameX  2019-01-01  token1     26     70
3  nameY  2018-09-01  tokenC    150    200
4  nameY  2018-07-04  tokenD     10     20
5  nameY  2019-01-01     NaN     50     50
6  nameY  2018-11-11  token2     50     20
7  nameY  2018-11-11  token2     50    100

以下是我想输出的内容:

    Token   Name  AggCost1  AggCost2        Date        -3mo  -3moCost1  -3moCost2        +3mo  +3moCost1  +3moCost2
0  token1  nameX        26        70  2019-01-01  2018-10-01         40         50  2019-04-01          0          0
1  token2  nameY       100       120  2018-11-11  2018-08-11        150        200  2019-02-11         50         50

我在生成中间表时遇到麻烦。我不确定如何根据第一个表中的Date将每个名称的行收集到-/ + 3个月的存储桶中。

    Name        Date        -3mo  -3moCost1  -3moCost2        +3mo  +3moCost1  +3moCost2
0  nameX  2019-01-01  2018-10-01         40         50  2019-03-31          0          0
1  nameY  2018-11-11  2018-08-11        150        200  2019-02-11         50         50

1 个答案:

答案 0 :(得分:0)

好的,我能够将一些东西拼凑在一起。我已经分解了下面的步骤。

我的起始数据帧:

df1

    Token   Name  AggCost1  AggCost2      Date1
0  token1  nameX        26        70 2019-01-01
1  token2  nameY       100       120 2018-11-11

df2

    Name      Date2   Token  Cost1  Cost2
0  nameX 2018-10-03  tokenA      0     30
1  nameX 2018-12-12  tokenB     40     20
2  nameX 2019-01-01  token1     26     70
3  nameY 2018-09-01  tokenC    150    200
4  nameY 2018-07-04  tokenD     10     20
5  nameY 2019-01-01     NaN     50     50
6  nameY 2018-11-11  token2     50     20
7  nameY 2018-11-11  token2     50    100

使用DateOffset

获取Date1前后三个月的日期
df1['-3mo'] = df1['Date1'] - pd.DateOffset(months=3)
df1['+3mo'] = df1['Date1'] + pd.DateOffset(months=3)

合并df1df2

df = pd.merge(df1, df2, how='left', on='Name')
  Token_x   Name  AggCost1  AggCost2      Date1       -3mo       +3mo      Date2 Token_y  Cost1  Cost2
0  token1  nameX        26        70 2019-01-01 2018-10-01 2019-04-01 2018-10-03  tokenA      0     30
1  token1  nameX        26        70 2019-01-01 2018-10-01 2019-04-01 2018-12-12  tokenB     40     20
2  token1  nameX        26        70 2019-01-01 2018-10-01 2019-04-01 2019-01-01  token1     26     70
3  token2  nameY       100       120 2018-11-11 2018-08-11 2019-02-11 2018-09-01  tokenC    150    200
4  token2  nameY       100       120 2018-11-11 2018-08-11 2019-02-11 2018-07-04  tokenD     10     20
5  token2  nameY       100       120 2018-11-11 2018-08-11 2019-02-11 2019-01-01     NaN     50     50
6  token2  nameY       100       120 2018-11-11 2018-08-11 2019-02-11 2018-11-11  token2     50     20
7  token2  nameY       100       120 2018-11-11 2018-08-11 2019-02-11 2018-11-11  token2     50    100

保留Date2落在Date1之前3个月或之后3个月内的行

df = df.loc[(df['Date2'] >= df['-3mo']) & (df['Date2'] < df['Date1']) 
       | (df['Date2'] > df['Date1']) & (df['Date2'] <= df['+3mo'])]

创建一列,将行分成-3mo或+ 3mo存储桶

df['3mo'] = np.where(df['Date2'] > df['Date1'], '+3', '-3')

使用新列获取Cost1和Cost2的汇总

df['3mo_Cost1'] = df.groupby(['3mo', 'Name'])['Cost1'].transform('sum')
df['3mo_Cost2'] = df.groupby(['3mo', 'Name'])['Cost2'].transform('sum')

将3mo_Cost1和3mo_Cost2分为两列

df['-3moCost1'] = np.where(df['3mo'] == '-3', df['3mo_Cost1'], 0)
df['+3moCost1'] = np.where(df['3mo'] == '+3', df['3mo_Cost1'], 0)
df['-3moCost2'] = np.where(df['3mo'] == '-3', df['3mo_Cost2'], 0)
df['+3moCost2'] = np.where(df['3mo'] == '+3', df['3mo_Cost2'], 0)

清洗后,这是最终的输出:

  Token_x   Name  AggCost1  AggCost2      Date1       -3mo  -3moCost1  -3moCost2       +3mo  +3moCost1  +3moCost2
0  token1  nameX        26        70 2019-01-01 2018-10-01         40         50 2019-04-01          0          0
3  token2  nameY       100       120 2018-11-11 2018-08-11        150        200 2019-02-11          0          0
5  token2  nameY       100       120 2018-11-11 2018-08-11          0          0 2019-02-11         50         50