提问人:AndysPythonStuff 提问时间:7/19/2023 最后编辑:AndysPythonStuff 更新时间:7/19/2023 访问量:51
在熊猫中使用 timedeltas 时考虑周末/节假日
Taking into account weekends/holidays when using timedeltas in pandas
问:
所以这里有一个问题,我花了一段时间才弄清楚为什么会这样......
我有一个值的数据帧,日期时间索引为工作日。
我添加了一个新列“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'
谁能看到一种无需重新索引即可做到这一点的简单方法?
谢谢!
答:
您可以使用该方法将索引移动给定的周期数。 下滑值(而不是索引),该值可用于根据上一行的值填充列中的缺失值。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])
评论
试试这个:
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
评论