在熊猫中使用 timedeltas 时考虑周末/节假日

Taking into account weekends/holidays when using timedeltas in pandas

提问人:AndysPythonStuff 提问时间:7/19/2023 最后编辑:AndysPythonStuff 更新时间:7/19/2023 访问量:51

问:

所以这里有一个问题,我花了一段时间才弄清楚为什么会这样......

我有一个值的数据帧,日期时间索引为工作日。

我添加了一个新列“ColB”,它始终与 colA 的值相同,但 colA 为 0 除外。然后我想使用 colA 的前几天值。

例如:

一个 B
2019-11-11 7 7
2019-11-12 3 3
2019-11-13 0 3
2019-11-14 5 5
2019-11-15 0 5

请注意 2019-11-13 的 colB 如何成为 2019-11-12 的 colA 值。15 日也一样:colB 从 14 日开始接受 colA。

我使用了这个列表理解:

df.loc[:,'colB'] = [df.loc[d-pd.Timedelta(1,'d'),'ColA'] if df.loc[d,'ColA']==0 else df.loc[d,'ColA'] for d in df.index]

我以为它不起作用(KeyError: Timestamp('2019-11-03 00:00:00')),但我发现问题出现是因为我在星期一有一个零,因此没有行是星期天。d-pd.Timedelta(1,'d')

我想当我在假期后的第二天也有零时也会发生同样的问题。

为了解决这个问题,当 col A 为零时,我实际上需要将 colA 中的前一个值用于 colB,而不是像 Ive 在列表推导中所做的那样使用之前的 DAYS 值。

我通过重新索引解决了这个问题,使用顺序号而不是日期,但我认为使用日期更好。

我试过shift:

df.loc[:,'colB'] = [df.loc[d,'ColA'].shift(-1) if df.loc[d,'ColA']==0 else df.loc[d,'ColA'] for d in df.index]

但出现错误:AttributeError: 'numpy.int64' object has no attribute 'shift'

谁能看到一种无需重新索引即可做到这一点的简单方法?

谢谢!

python pandas list-comprehension timedelta shift

评论


答:

1赞 Christian 7/19/2023 #1

您可以使用该方法将索引移动给定的周期数。 下滑值(而不是索引),该值可用于根据上一行的值填充列中的缺失值。shift()shift()

您可以将其与函数结合使用,该函数将替换条件为 False 的值。where()

df['ColB'] = df['ColA'].where(df['ColA'] != 0, df['ColA'].shift(1))

这将创建一个新列“ColB”,如果“ColA”不为零,则为其分配“ColA”值。如果“ColA”为零,则它从“ColA”的前一行中获取值。

若要同时处理第一行,请使用该函数。此函数将 NA/NaN 值替换为指定值。fillna()

在下面的示例中,如果“ColA”的第一行为 0,则它将替换为“ColA”中的第二个值。如果要将其替换为其他值,可以将下面替换为所需的值。df['ColA'][0]

df['ColB'] = df['ColA'].where(df['ColA'] != 0, df['ColA'].shift(1)).fillna(df['ColA'][0])

评论

1赞 AndysPythonStuff 7/19/2023
哇,太快了!我正在编辑问题,因为我使用shift的方式不起作用。你的似乎效果很好!谢谢!
1赞 rhug123 7/19/2023 #2

试试这个:

df.assign(B = df['A'].replace(0))

输出:

          Day  A  B
0  2019-11-11  7  7
1  2019-11-12  3  3
2  2019-11-13  0  3
3  2019-11-14  5  5
4  2019-11-15  0  5

评论

0赞 AndysPythonStuff 7/20/2023
这很酷,虽然超出了我的理解。我不明白为什么 df['A'].replace(0) 没有在有零的地方留下 nans。我在程序中测试了它,它使用了 A 列中的上一个值,因为它应该,
1赞 AndysPythonStuff 7/20/2023
啊哈!“当 value 未显式传递且 to_replace 是标量、列表或元组时,replace 使用方法参数(默认为 'pad')进行替换。”那是一个半教程!谢谢!