如何让Pandas DataFrame的shift()按行而非日期跳转(指定工作日)
问题:Pandas shift()按日期偏移而非行跳转导致NaN
从原DataFrame筛选出仅包含周一、周三、周五的行(通过Shapes==1标记)生成了data2,但使用shift()时发现它按日期逐天偏移,导致出现NaN值。需要让shift()直接在data2的行与行之间跳转,忽略日期间隔。
原代码
print(data) data2=data[(data["Shapes"])==1] rango= pdta.sma(((data2.high/data2.low)-1)*100,3) data3 = data2[((((1-(data2.close/data2.shift().close))*100>1.73) | ((1-(data2.close/data2.shift().close))*100<-2) | ((1-(data2.high/data2.shift().close))*100>1.73) | ((1-(data2.low/data2.shift().close))*100<-2))) & (rango>2.3)] data4= data2[((((1-(data2.close/data2.shift().close))*100<1.73) & ((1-(data2.close/data2.shift().close))*100>-2)) ) & (rango>2.3) ] data3["tasa"]=abs((1-(data2.close/data2.shift().close))*100) data4["tasa"]=abs((1-(data2.close/data2.shift().close))*100) data3["acc"]=data3["tasa"].cumsum() print(data2) print(data3)
运行结果
原DataFrame(data)片段
open high low close Shapes MA Smoothing Line MA.1 Smoothing Line.1 DIVATR2 CCI Smoothing Line.2 time 2017-01-03 14:30:00 2251.57 2258.21 2251.57 2255.44 0 NaN NaN NaN NaN NaN NaN NaN 2017-01-03 15:00:00 2255.61 2263.88 2255.06 2261.02 0 NaN NaN NaN NaN NaN NaN NaN ... 2022-12-09 21:00:00 3934.12 3934.39 3934.12 3934.39 1 3986.26665 3986.42515 3993.3376 3995.32568 0.278829 -276.147235 -140.659208 [20878 rows x 12 columns]
筛选后的DataFrame(data2)片段
open high low close Shapes MA Smoothing Line MA.1 Smoothing Line.1 DIVATR2 CCI Smoothing Line.2 time 2017-01-04 21:00:00 2270.53 2270.76 2270.53 2270.75 1 NaN NaN NaN NaN 0.145114 64.620644 75.006245 2017-01-06 21:00:00 2277.24 2277.24 2276.98 2276.98 1 NaN NaN NaN NaN 0.126855 41.738705 78.922137 ... 2022-12-09 21:00:00 3934.12 3934.39 3934.12 3934.39 1 3986.26665 3986.42515 3993.3376 3995.32568 0.278829 -276.147235 -140.659208 [877 rows x 12 columns]
解决方案
问题根源是data2使用时间序列索引,默认shift()会按时间间隔偏移,而筛选后的时间不连续,因此出现NaN。只需将data2的索引重置为连续整数,即可让shift()按行跳转。
修改后的代码示例
# 重置data2索引为连续整数,丢弃原时间索引 data2 = data[(data["Shapes"])==1].reset_index(drop=True) # 后续操作保持不变,此时shift()将按行跳转 rango= pdta.sma(((data2.high/data2.low)-1)*100,3) data3 = data2[((((1-(data2.close/data2.shift().close))*100>1.73) | ((1-(data2.close/data2.shift().close))*100<-2) | ((1-(data2.high/data2.shift().close))*100>1.73) | ((1-(data2.low/data2.shift().close))*100<-2))) & (rango>2.3)] data4= data2[((((1-(data2.close/data2.shift().close))*100<1.73) & ((1-(data2.close/data2.shift().close))*100>-2)) ) & (rango>2.3) ] data3["tasa"]=abs((1-(data2.close/data2.shift().close))*100) data4["tasa"]=abs((1-(data2.close/data2.shift().close))*100) data3["acc"]=data3["tasa"].cumsum() print(data2) print(data3)
原理说明
- 时间索引下,
shift()默认按时间单位偏移,而筛选后的时间并非连续,因此无法找到对应偏移日期的数据,产生NaN。 - 重置为连续整数索引后,
shift(1)直接指向DataFrame中的上一行数据,完全忽略原时间间隔,满足需求。
内容的提问来源于stack exchange,提问作者Pablo Lleo Garcia
相关产品推荐
相关产品推荐

