【问题标题】:Rolling window produces no effect on dataframe滚动窗口对数据框没有影响
【发布时间】:2022-01-04 02:19:25
【问题描述】:

所以我必须对数据框内的一组行执行滚动窗口。问题是当我执行full_df = full_df.rolling(window=5).mean() 时,full_df.head(2000) 的输出显示所有 NaN 值。有谁知道为什么会这样?我必须对此进行时间序列练习。

这是数据集:https://github.com/plotly/datasets/blob/master/all_stocks_5yr.csv

这就是我所拥有的:

df = pd.read_csv('all_stocks_5yr.csv', usecols=["date", "close", 
"Name"])

gp = df.groupby("Name")
my_dict = {key: group['close'].to_numpy() for key, group in gp}

full_df = pd.DataFrame.from_dict(my_dict, orient='index')
for i in full_df:
    full_df = full_df.rolling(window=5).mean()

输出的图像:

【问题讨论】:

    标签: python dataframe csv dictionary


    【解决方案1】:

    首先,您的循环for i in full_df 没有按照您的想法进行;您不是在每一行中运行滚动平均值,而是在整个数据帧上一遍又一遍地运行它,沿列平均。

    如果我们只是按照您的实现方式进行滚动平均:

    full_df = full_df.rolling(window=5).mean()
    print(full_df)
              0         1         2         3     ...     1255    1256     1257     1258
    A          NaN       NaN       NaN       NaN  ...      NaN     NaN      NaN      NaN
    AAL        NaN       NaN       NaN       NaN  ...      NaN     NaN      NaN      NaN
    AAP        NaN       NaN       NaN       NaN  ...      NaN     NaN      NaN      NaN
    AAPL       NaN       NaN       NaN       NaN  ...      NaN     NaN      NaN      NaN
    ABBV  48.56684  48.37228  47.95056  48.07312  ...  102.590  98.768  101.212  100.510
    ...        ...       ...       ...       ...  ...      ...     ...      ...      ...
    XYL   45.58400  45.60000  45.74000  45.96200  ...   64.504  61.854   61.596   61.036
    YUM   51.14200  51.01800  51.17400  51.28400  ...   66.902  64.420   63.914   63.668
    ZBH   48.59000  48.49200  48.57000  48.75000  ...   75.154  73.112   72.704   72.436
    ZION  44.84400  44.76600  44.89400  45.08200  ...   73.972  71.734   71.516   71.580
    ZTS   45.08600  45.02600  45.27400  45.39200  ...   83.002  80.224   80.000   80.116
    
    [505 rows x 1259 columns]
    

    前四行都是NaN,因为滚动平均值未定义为少于 5 行。

    如果我们再做一次(总共做两次):

    full_df = full_df.rolling(window=5).mean()
    print(full_df.head(9))
               0          1          2     ...      1256      1257      1258
    A           NaN        NaN        NaN  ...       NaN       NaN       NaN
    AAL         NaN        NaN        NaN  ...       NaN       NaN       NaN
    AAP         NaN        NaN        NaN  ...       NaN       NaN       NaN
    AAPL        NaN        NaN        NaN  ...       NaN       NaN       NaN
    ABBV        NaN        NaN        NaN  ...       NaN       NaN       NaN
    ABC         NaN        NaN        NaN  ...       NaN       NaN       NaN
    ABT         NaN        NaN        NaN  ...       NaN       NaN       NaN
    ACN         NaN        NaN        NaN  ...       NaN       NaN       NaN
    ADBE  49.619072  49.471424  49.192048  ...  108.3420  110.4848  110.4976
    

    您可以看到前 8 行都是NaN,因为第四行在滚动平均值中下降到第八。给定数据框的大小(505 行),如果您运行滚动平均值 127 次,则整个 df 将被 NaN 值消耗,而您的 for 循环执行的次数甚至更多,这这就是为什么您的 df 充满了 NaN 值。

    另外,请注意,您正在对不同的股票代码进行平均,这是没有意义的。我相信你想要做的是averaging the rows, not the columns 在这种情况下你只需要这样做

    full_df = full_df.rolling(axis = 'columns', window=5).mean()
    print(full_df)
          0     1     2     3         4        5     ...     1253     1254     1255     1256     1257     1258
    A      NaN   NaN   NaN   NaN  44.72600  44.1600  ...   73.926   73.720   73.006   71.744   70.836   69.762
    AAL    NaN   NaN   NaN   NaN  14.42600  14.3760  ...   53.142   53.308   53.114   52.530   52.248   51.664
    AAP    NaN   NaN   NaN   NaN  78.74000  78.7600  ...  120.742  120.016  118.074  115.468  114.054  112.642
    AAPL   NaN   NaN   NaN   NaN  67.32592  66.9025  ...  168.996  168.330  166.128  163.834  163.046  161.468
    ABBV   NaN   NaN   NaN   NaN  35.87200  36.1380  ...  116.384  117.992  116.384  113.824  112.888  113.168
    ...    ...   ...   ...   ...       ...      ...  ...      ...      ...      ...      ...      ...      ...
    XYL    NaN   NaN   NaN   NaN  27.84600  28.0840  ...   73.278   73.598   73.848   73.698   73.350   73.256
    YUM    NaN   NaN   NaN   NaN  64.58000  64.3180  ...   85.504   85.168   84.454   83.118   82.316   81.424
    ZBH    NaN   NaN   NaN   NaN  75.85600  75.8660  ...  126.284  126.974  126.886  126.044  125.316  124.048
    ZION   NaN   NaN   NaN   NaN  24.44200  24.4820  ...   53.838   54.230   54.256   53.748   53.466   53.464
    ZTS    NaN   NaN   NaN   NaN  33.37400  33.5600  ...   78.720   78.434   77.772   76.702   75.686   75.112
    

    同样,您的前四列不在此处管理。

    为了更正这一点,我们再添加一个术语:

    full_df = full_df.rolling(axis = 'columns', window=5, min_periods = 1).mean()
    print(full_df)
             0        1          2        3         4        5     ...     1253     1254     1255     1256     1257     1258
    A     45.0800  44.8400  44.766667  44.7625  44.72600  44.1600  ...   73.926   73.720   73.006   71.744   70.836   69.762
    AAL   14.7500  14.6050  14.493333  14.5350  14.42600  14.3760  ...   53.142   53.308   53.114   52.530   52.248   51.664
    AAP   78.9000  78.6450  78.630000  78.7150  78.74000  78.7600  ...  120.742  120.016  118.074  115.468  114.054  112.642
    AAPL  67.8542  68.2078  67.752800  67.4935  67.32592  66.9025  ...  168.996  168.330  166.128  163.834  163.046  161.468
    ABBV  36.2500  36.0500  35.840000  35.6975  35.87200  36.1380  ...  116.384  117.992  116.384  113.824  112.888  113.168
    ...       ...      ...        ...      ...       ...      ...  ...      ...      ...      ...      ...      ...      ...
    XYL   27.0900  27.2750  27.500000  27.6900  27.84600  28.0840  ...   73.278   73.598   73.848   73.698   73.350   73.256
    YUM   65.3000  64.9250  64.866667  64.7525  64.58000  64.3180  ...   85.504   85.168   84.454   83.118   82.316   81.424
    ZBH   75.8500  75.7500  75.646667  75.7350  75.85600  75.8660  ...  126.284  126.974  126.886  126.044  125.316  124.048
    ZION  24.1400  24.1750  24.280000  24.3950  24.44200  24.4820  ...   53.838   54.230   54.256   53.748   53.466   53.464
    ZTS   33.0500  33.1550  33.350000  33.4000  33.37400  33.5600  ...   78.720   78.434   77.772   76.702   75.686   75.112
    
    

    在上面的数据框中,第一列是时间0的值,第二列是01的时间平均值,第三列是01的时间平均值, 和 2 等。窗口大小会继续增长,直到达到 window=5 的值,此时窗口会随着滚动平均值一起移动。请注意,您也可以center the rolling mean,如果您想要而不是有一个尾随窗口。你可以看到documentation here

    【讨论】:

      【解决方案2】:

      我不太确定您要做什么。您能否更详细地解释一下您的运营目标是什么?我假设您尝试在每个资产上建立一个以 5 天为间隔的移动(滚动)平均值,并计算每个间隔的平均价格。

      但首先,让我回答为什么你会看到所有的 NaN: 您在下面的代码中所做的是,您只是一遍又一遍地执行相同的操作,其结果始终是 NaN。也就是说,因为你对 dict 做了一些奇怪的事情,并且第一行都有 NaN,所以平均值也将是 NaN。而且由于您通过此计算的结果覆盖了变量 full_df,因此您的数据框仅显示 NaN。

      for i in full_df:
          full_df = full_df.rolling(window=5).mean()
      

      让我更详细地解释一下。您(可能)试图迭代数据框(使用 5 天的窗口)并计算平均值。函数full_df.rolling(window=5).mean() 已经做到了这一点,并且输出是一个新的数据帧,每个窗口在整个数据帧full_df 上的平均值。通过在循环中运行此函数,无需额外的索引,您只需在整个数据帧中重复运行相同的函数。

      也许这会让你得到你想要的:

      import pandas as pd
      
      df = pd.read_csv("all_stocks_5yr.csv", index_col=[0,6])
      
      means = df.rolling(window=5).mean()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-23
        • 1970-01-01
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 2020-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多