首页 > 解决方案 > 熊猫滚动申请返回 np.nan

问题描述

我想将自定义偏度函数应用于滚动应用,但得到了 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

标签: pythonpandas

解决方案


通过loccol每次迭代中修改实际的 DataFrame 。列中的引入NaN最终意味着窗口变成了所有NaN。最简单的解决方法(不了解如何应用偏度的更多信息)是创建一个副本col进行处理:

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

推荐阅读