我想将自定义偏度函数应用于滚动应用,但得到了 np.nan。
import pandas as pd
import numpy as np
def _get_skewness(col, q=(0.05, 0.95)):
if q[0] > 0:
quantiles = col.quantile(q)
col.loc[(col<quantiles[q[0]]) | (col > quantiles[q[1]])] = np.nan
skew = col.skew(axis=0, skipna=True)
return skew
df = pd.DataFrame(np.arange(40).reshape(-1, 2))
df_skew = df.rolling(20, 10).apply(_get_skewness)
print(df_skew)
我得到了以下结果。我知道前 10 行是由于滚动窗口 min_period=10。只是不明白为什么最后几行也返回 np.nan。
0 1
0 NaN NaN
1 NaN NaN
2 NaN NaN
3 NaN NaN
4 NaN NaN
5 NaN NaN
6 NaN NaN
7 NaN NaN
8 NaN NaN
9 0.0 0.0
10 0.0 0.0
11 0.0 0.0
12 0.0 0.0
13 0.0 0.0
14 0.0 0.0
15 NaN NaN
16 NaN NaN
17 NaN NaN
18 NaN NaN
19 NaN NaN
答案 0 :(得分:1)
通过在 loc
上使用 col
,每次迭代都会修改实际的 DataFrame。列中NaN
的引入最终意味着窗口变成了所有NaN
。最简单的解决方法(不了解更多关于如何应用偏度的方法)是创建一个 col
的 copy 来处理:
def _get_skewness(col, q=(0.05, 0.95)):
copy_col = col.copy() # Make a copy so as to not overwrite future values.
if q[0] > 0:
quantiles = copy_col.quantile(q)
copy_col.loc[
(copy_col < quantiles[q[0]]) | (copy_col > quantiles[q[1]])
] = np.nan
skew = copy_col.skew(axis=0, skipna=True)
return skew
df = pd.DataFrame(np.arange(40).reshape(-1, 2))
df_skew = df.rolling(20, 10).apply(_get_skewness)
df_skew
:
0 1
0 NaN NaN
1 NaN NaN
2 NaN NaN
3 NaN NaN
4 NaN NaN
5 NaN NaN
6 NaN NaN
7 NaN NaN
8 NaN NaN
9 0.0 0.0
10 0.0 0.0
11 0.0 0.0
12 0.0 0.0
13 0.0 0.0
14 0.0 0.0
15 0.0 0.0
16 0.0 0.0
17 0.0 0.0
18 0.0 0.0
19 0.0 0.0