为什么我在计算波动率时得到 NaN?

问题描述

我正在尝试按照本文 here 上的方程计算功率时间序列数据的历史波动率。

数据统计说明如下:

count    9855.000000
mean      291.135088
std       187.503344
min         0.000000
25%       112.408512
50%       332.370871
75%       449.527323
max       601.370058

这是我的实现:


# Computing Volatility
window_size=27
VOLATILITY = pd.DataFrame()
VOLATILITY['PV']= data
#'intra-hour
# Compute the logarithmic value  
VOLATILITY['Log_IA'] = np.log(VOLATILITY['PV'] / VOLATILITY['PV'].shift(1))
# Compute Volatility using the pandas rolling standard deviation function
VOLATILITY['intra-hour'] = VOLATILITY['Log_IA'].rolling(window=window_size).std() * np.sqrt(window_size)# *100

我的数据有 1 年每半小时观察每天 27 步

这是我在存在 NaN 问题的 1 天得到的输出示例

    
Timestamp           PV          Log_IA     intra-hour
2019-03-01 06:00:00 0.000000    NaN         NaN
2019-03-01 06:30:00 2.946333    inf         NaN
2019-03-01 07:00:00 20.963667   1.962229    NaN
2019-03-01 07:30:00 38.284333   0.602250    NaN
2019-03-01 08:00:00 38.224667   -0.001560   NaN
2019-03-01 08:30:00 54.486667   0.354475    NaN
2019-03-01 09:00:00 54.608333   0.002230    NaN
2019-03-01 09:30:00 55.290667   0.012418    NaN
2019-03-01 10:00:00 54.317333   -0.017761   NaN
2019-03-01 10:30:00 54.680333   0.006661    NaN
2019-03-01 11:00:00 42.142333   -0.260451   NaN
2019-03-01 11:30:00 44.569000   0.055986    NaN
2019-03-01 12:00:00 36.988333   -0.186436   NaN
2019-03-01 12:30:00 35.802000   -0.032599   NaN
2019-03-01 13:00:00 29.006667   -0.210478   NaN
2019-03-01 13:30:00 43.254333   0.399572    NaN
2019-03-01 14:00:00 45.246333   0.045024    NaN
2019-03-01 14:30:00 29.768333   -0.418676   NaN
2019-03-01 15:00:00 37.510667   0.231180    NaN
2019-03-01 15:30:00 31.937000   -0.160860   NaN
2019-03-01 16:00:00 39.990333   0.224873    NaN
2019-03-01 16:30:00 32.263000   -0.214717   NaN
2019-03-01 17:00:00 40.707333   0.232487    NaN
2019-03-01 17:30:00 14.551333   -1.028726   NaN
2019-03-01 18:00:00 10.294333   -0.346089   NaN
2019-03-01 18:30:00 2.552667    -1.394455   NaN
2019-03-01 19:00:00 0.036333    -4.252158   NaN

那么,为什么我会因为波动而得到 NaN?

我的实现有问题吗?

解决方法

您的实现是这样的,无论 NaN 的值如何,您将始终获得 Log_IA 的第零个值的 PV。这是转移的结果,可以通过运行以下代码段来确认:

import numpy as np
import pandas as pd


VOLATILITY = pd.DataFrame()
VOLATILITY['PV'] = (1.0,2.0,3.0)
VOLATILITY['Log_IA'] = np.log(VOLATILITY['PV'] / VOLATILITY['PV'].shift(1))

您会看到 VOLATILITY 是:

    PV    Log_IA
0  1.0       NaN
1  2.0  0.693147
2  3.0  0.405465

Log_IA 的第零个值是 NaN,因为您将 \log{1.0} 除以 PV 的前一个值,即索引处 PV 的值-1.这就是 shift() 的作用,但在索引 -1 处没有值,因此您得到 NaN。您可以使用 fill_value 参数设置一个值来代替任何不存在的值:shift(1,fill_value=123)。当前一个索引的 inf 值为 0 时,您还将为 Log_IA 的任何值获得 PV

那么为什么 NaN 的所有值都是 intra-hour?您采用 VOLATILITY['Log_IA'].rolling(window=window_size) 的滚动标准偏差,它在索引 0 处包含 inf,对于包含 inf 的序列,标准偏差未定义。所以滚动标准偏差是 NaN,任何带有 NaN 的算术运算都会导致 NaN

现在,您的代码中的 \log{0} 也有问题。对于小于或等于 0 的值,未定义对数,但这不是导致 NaN 出现的原因。

https://www.varsitytutors.com/hotmath/hotmath_help/topics/logarithmic-functions.html

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...