gpt4 book ai didi

python - 如何将不同长度的时间窗应用于 Pandas 数据框

转载 作者:太空宇宙 更新时间:2023-11-04 04:00:56 25 4
gpt4 key购买 nike

我有以下数据框,每一行代表一个销售交易:

startDate           INDEX_250   priceDeal
2013-05-02 00:00:00 9312.000 255000.000
2013-09-17 00:00:00 11121.000 368209.000
2013-10-09 00:00:00 11121.000 254000.000
2013-11-14 00:00:00 11121.000 520000.000
2013-11-22 00:00:00 11121.000 201000.000
2014-02-05 00:00:00 11121.000 260000.000
2014-02-28 00:00:00 11121.000 425000.000
2014-03-01 00:00:00 11121.000 315000.000
2014-03-11 00:00:00 9312.000 427000.000
2014-04-27 00:00:00 9312.000 138070.000
2014-06-20 00:00:00 9312.000 270000.000
2014-07-21 00:00:00 9312.000 282000.000
2014-07-31 00:00:00 9312.000 308806.350
2014-09-27 00:00:00 11121.000 170000.000
2014-10-05 00:00:00 11121.000 171658.220
2014-10-11 00:00:00 11121.000 292000.000
2014-10-13 00:00:00 11121.000 125000.000
2014-10-30 00:00:00 9312.000 95000.000
2014-11-18 00:00:00 9312.000 158942.280
2015-01-25 22:00:00 11121.000 238829.370
2015-03-11 00:00:00 11121.000 180695.960
2015-03-14 00:00:00 9312.000 320932.860
2015-03-21 00:00:00 11121.000 139872.000
2015-09-04 00:00:00 11121.000 140000.000
2015-09-09 00:00:00 9312.000 235000.000

我想查看在过去的 30 天 nrTargets_gr_250_30 和 60 天 nrTargets_gr_250_60 中发生了多少销售交易(分组依据)INDEX_250 来自第一次销售交易 2013-09-17。示例数据集仅适用于一个 INDEX_250 但也有其他索引号,下面的输出是可取的:

      startDate  INDEX_250  nrTargets_gr_250_30 nrTargets_gr_250_60
2013-10-17 11121 2.000 2.000
2013-11-16 11121 1.000 3.000
2013-12-16 11121 1.000 2.000
2014-01-15 11121 0.000 1.000
2014-02-14 11121 1.000 1.000
2014-03-16 11121 2.000 3.000
2014-04-15 11121 0.000 2.000
2014-10-12 11121 3.000 3.000
2014-11-11 11121 1.000 4.000
2014-12-11 11121 0.000 1.000
2015-02-09 11121 1.000 1.000
2015-03-11 11121 0.000 1.000
2015-04-10 11121 2.000 2.000
2015-05-10 11121 0.000 2.000
2015-09-07 11121 1.000 1.000
2015-10-07 11121 0.000 1.000
2016-02-04 11121 1.000 1.000
2016-03-05 11121 0.000 1.000
2017-01-29 11121 1.000 1.000

最佳答案

我注意到您希望将 startDate 更改为各自的末尾30 天期限,从您的开始日期开始。

另一个细节是您希望结果按INDEX_250分组 -有多少以前的交易(在两个各自的时期)与INDEX_250相同值。

另请注意,可以在窗口上执行滚动计算包含多个 future 期间的行,而您想要 30 或 60 天的交易次数,以及滚动 不允许负数的周期。

这就是为什么我采用了不同于“普通”滚动的方法。

从辅助变量开始:

td30 = pd.Timedelta('30D')
dRng = pd.date_range(start='2013-09-17', end=df.startDate.max() + td30,
freq='30D', closed='left')

然后定义以下计算两个目标的函数:

def targets(grp):
grp['Prd'] = grp.startDate.apply(lambda x: dRng.asof(x) + td30)
grp.set_index('Prd', inplace=True)
trg30 = grp.groupby(level=0).INDEX_250.count()\
.rename('nrTargets_gr_250_30').reindex(dRng, fill_value=0)
trg60 = trg30.rolling(2).sum().rename('nrTargets_gr_250_60')\
.fillna(0, downcast='infer')
trg30 = trg30[trg30 > 0]
trg60 = trg60[trg60 > 0]
return trg30.to_frame().join(trg60, how='outer')\
.fillna(0, downcast='infer').rename_axis('startDate')

应用它并重置索引(只是按此顺序,以正确排列列):

df2 = df[df.startDate >= '2013-09-17'].groupby('INDEX_250')\
.apply(targets).reset_index(level=[0]).reset_index()

注意事项:

  • 我只获取了 startDate 在您的开始日期或之后的行指定(2013-09-17)。
  • 目标 列的类型都是int。我觉得比较自然因为这些列包含交易的数量,从本质上讲只是一个整数

最后一件事是将 INDEX_250 的类型更改为 int:

df2.INDEX_250 = df2.INDEX_250.astype(int)

INDEX_250 组的结果与您指定的一样,不包括20162017 的结果行,这些行未包含在您的示例数据。

加长版 - 平均价格

通过每个“最终”日期的平均价格扩展结果和两个目标,需要进行两个更改。

首先,定义另一个函数来“重新格式化”目标 DataFrame:

def trgReformat(trg):
trg = trg[trg.nrTargets_gr_250 > 0].copy()
trg['avgPrice'] = trg.sm / trg.nrTargets_gr_250
return trg.drop(columns='sm')

其次,将目标函数定义为:

def targets(grp):
grp['Prd'] = grp.startDate.apply(lambda x: dRng.asof(x) + td30)
grp.set_index('Prd', inplace=True)
trg30 = grp.groupby(level=0).agg(
nrTargets_gr_250=('INDEX_250', 'count'), sm=('priceDeal', 'sum'))\
.reindex(dRng, fill_value=0)
trg60 = trg30.rolling(2).sum().fillna(0, downcast='infer')
trg30 = trgReformat(trg30)
trg60 = trgReformat(trg60)
return trg30.join(trg60, how='outer', lsuffix='_30', rsuffix='_60')\
.fillna(0, downcast='infer').rename_axis('startDate')

此函数使用命名聚合来计算:

  • nrTargets_gr_250 - 行数,
  • sm - 价格总和。

原因是 trg60 的计算是使用rolling 执行的(对于2 个连续的 30 天周期),因此仅平均值是不够的在这里。

平均价格的计算可以在重新格式化时执行每个目标

这个函数的应用和以前一样。

关于python - 如何将不同长度的时间窗应用于 Pandas 数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58356398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com