【问题标题】:Comparing daily value in each year in DataFrame to same day-number's value in another specific year将 DataFrame 中每年的每日值与另一个特定年份的同一天数的值进行比较
【发布时间】:2019-07-22 17:36:46
【问题描述】:

我有一个可以追溯到 1990 年的金融工具的每日收盘价时间序列。

我正在尝试将前几年每个交易日的每日百分比变化与 2019 年的相应交易日进行比较。我目前有 2019 年 41 个交易日的数据。

到目前为止,我已经过滤并创建了一个新的 DataFrame,其中只有前 41 个日期、收盘价、每日百分比变化以及集合中每一天的“一年中的交易日”(“tdoy”)分类器,但我没有从那里走运。

我发现了其他 Stack Overflow 问题,可以帮助人们比较 datetime 天、周、年等,但由于每个“tdoy”代表的任意值,我无法重新创建。

由于行数的原因,我不会费心创建示例 DataFrame,因此我已将我提出的 CSV 链接到这一点:Sample CSV

我认为最简单的方法就是创建一个新列,使用df.loc 返回每​​个相应“tdoy”(一年中的交易日)的 2019 年百分比变化,如果我能想出这么多,我然后可以创建另一个列来计算该年/日的百分比变化与 2019 年的相应值之间的简单差异。以下是我尝试使用的(并且我尝试了其他变体)无济于事。 df['2019'] = df['perc'].loc[((df.year == 2019) & (df.tdoy == df.tdoy))]

我尝试在我的问题的大约 20 种不同变体中搜索 Stack 和 Google,但似乎找不到适合我任意“一年中的交易日”分类问题的答案。

我确信答案就在我眼前,但我对数据争论仍然不熟悉。

【问题讨论】:

    标签: python pandas dataframe compare time-series


    【解决方案1】:

    第一步是正确导入 csv。我不确定您是否进行了调整,但您的数据的日期列是一个字符串对象。

    # import the csv and assign to df. parse dates to datetime
    df = pd.read_csv('TimeSeriesEx.csv', parse_dates=['Dates'])
    
    # filter the dataframe so that you only have 2019 and 2018 data
    df=df[df['year'] >= 2018]
    df.tail()
    
        Unnamed: 0  Dates       last    perc        year    tdoy
    1225    7601    2019-02-20  29.96   0.007397    2019    37
    1226    7602    2019-02-21  30.49   0.017690    2019    38
    1227    7603    2019-02-22  30.51   0.000656    2019    39
    1228    7604    2019-02-25  30.36   -0.004916   2019    40
    1229    7605    2019-02-26  30.03   -0.010870   2019    41
    

    将 tdoy 和 year 放入一个多索引中。

    # create a multiindex
    df.set_index(['tdoy','year'], inplace=True)
    
    df.tail()
    
                        Dates       last    perc
    tdoy    year                
    37  2019    7601    2019-02-20  29.96   0.007397
    38  2019    7602    2019-02-21  30.49   0.017690
    39  2019    7603    2019-02-22  30.51   0.000656
    40  2019    7604    2019-02-25  30.36   -0.004916
    41  2019    7605    2019-02-26  30.03   -0.010870
    

    制作数据透视表

    # make a pivot table and assign it to a variable
    df1 = df.pivot_table(values='last', index='tdoy', columns='year')
    
    df1.head()
    
    year 2018   2019
    tdoy        
    1   33.08   27.55
    2   33.38   27.90
    3   33.76   28.18
    4   33.74   28.41
    5   33.65   28.26
    

    创建计算列

    # create the new column
    df1['pct_change'] = (df1[2019]-df1[2018])/df1[2018]
    
    df1
    
    year 2018   2019    pct_change
    tdoy            
    1   33.08   27.55   -0.167170
    2   33.38   27.90   -0.164170
    3   33.76   28.18   -0.165284
    4   33.74   28.41   -0.157973
    5   33.65   28.26   -0.160178
    6   33.43   28.18   -0.157045
    7   33.55   28.32   -0.155887
    8   33.29   27.94   -0.160709
    9   32.97   28.17   -0.145587
    10  32.93   28.11   -0.146371
    11  32.93   28.24   -0.142423
    12  32.79   28.23   -0.139067
    13  32.51   28.77   -0.115042
    14  32.23   29.01   -0.099907
    15  32.28   29.01   -0.101301
    16  32.16   29.06   -0.096393
    17  32.52   29.38   -0.096556
    18  32.68   29.51   -0.097001
    19  32.50   30.03   -0.076000
    20  32.79   30.30   -0.075938
    21  32.87   30.11   -0.083967
    22  33.08   30.42   -0.080411
    23  33.07   30.17   -0.087693
    24  32.90   29.89   -0.091489
    25  32.51   30.13   -0.073208
    26  32.50   30.38   -0.065231
    27  33.16   30.90   -0.068154
    28  32.56   30.81   -0.053747
    29  32.21   30.87   -0.041602
    30  31.96   30.24   -0.053817
    31  31.85   30.33   -0.047724
    32  31.57   29.99   -0.050048
    33  31.80   29.89   -0.060063
    34  31.70   29.95   -0.055205
    35  31.54   29.95   -0.050412
    36  31.54   29.74   -0.057070
    37  31.86   29.96   -0.059636
    38  32.07   30.49   -0.049267
    39  32.04   30.51   -0.047753
    40  32.36   30.36   -0.061805
    41  32.62   30.03   -0.079399
    

    完全没有 cmets 和数据,代码如下:

    df = pd.read_csv('TimeSeriesEx.csv', parse_dates=['Dates'])
    df=df[df['year'] >= 2018]
    df.set_index(['tdoy','year'], inplace=True)
    df1 = df.pivot_table(values='last', index='tdoy', columns='year')
    df1['pct_change'] = (df1[2019]-df1[2018])/df1[2018]
    

    [EDIT] 海报要求提供与 2019 年相比的所有日期。

    df = pd.read_csv('TimeSeriesEx.csv', parse_dates=['Dates'])
    df.set_index(['tdoy','year'], inplace=True)
    

    忽略上面的年份过滤器,创建数据透视表

    df1 = df.pivot_table(values='last', index='tdoy', columns='year')
    

    创建一个遍历年份/列的循环,并为与 2019 年相比的每一年创建一个新字段。

    for y in df1.columns:    
        df1[str(y) + '_pct_change'] = (df1[2019]-df1[y])/df1[y]
    

    查看一些数据...

    df1.loc[1:4, "1990_pct_change":"1994_pct_change"]
    
    year    1990_pct_change 1991_pct_change 1992_pct_change 1993_pct_change 1994_pct_change
    tdoy                    
    1       0.494845        0.328351        0.489189        0.345872    -0.069257
    2       0.496781        0.364971        0.516304        0.361640    -0.045828
    3       0.523243        0.382050        0.527371        0.369956    -0.035262
    4       0.524960        0.400888        0.531536        0.367838    -0.034659
    

    所有年份的最终代码:

    df = pd.read_csv('TimeSeriesEx.csv', parse_dates=['Dates'])
    df.set_index(['tdoy','year'], inplace=True)
    df1 = df.pivot_table(values='last', index='tdoy', columns='year')
    for y in df1.columns:    
        df1[str(y) + '_pct_change'] = (df1[2019]-df1[y])/df1[y]
    
    df1
    

    【讨论】:

    • 感谢您的回复。也许我正在寻找的最终结果并不是实现我的最终目标的最有效方法,即根据每日百分比变化值的趋势找到最相似的年份。在没有某种循环的情况下,有没有办法改变你在上面所做的计算,不仅针对 2018 年与 2019 年,而且针对 1990-2018 年与 2019 年的每一年进行计算?
    • 您到底在寻找哪种趋势?
    • 这很有帮助。谢谢你。这是我以前没有考虑过的一种方法。我还制定了创建一个新的 df 仅 2019 tdoyperc 值并将它们压缩到 dict,然后在原始数据框上创建一个新列,映射 tdoy 作为其关键dict 中的值对。然后创建另一列以找出当年值与 2019 年值之间的差值并将其平方。然后我需要做一些 groupby year 函数找到最低值来得出最相似的年份。我可能会创建自己的答案作为替代方案,但枢轴很有帮助。
    • 关于我在寻找什么趋势,我最终计划进行某种小波变换(目前还很少)以将前几年的规模与我正在与(2019)进行比较的年份。目前,我只是想找出哪一年与 2019 年的每日百分比变化差异最小,然后我可以说,根据该计算,例如,与 2019 年相比,1999 年的百分比变化趋势最相似。
    【解决方案2】:

    我也想出了我自己的答案,更符合我最初想要完成的目标。我将使用 DataFrame 作为示例。 df:

    Dates last perc year tdoy 0 2016-01-04 29.93 -0.020295 2016 2 1 2016-01-05 29.63 -0.010023 2016 3 2 2016-01-06 29.59 -0.001350 2016 4 3 2016-01-07 29.44 -0.005069 2016 5 4 2017-01-03 34.57 0.004358 2017 2 5 2017-01-04 34.98 0.011860 2017 3 6 2017-01-05 35.00 0.000572 2017 4 7 2017-01-06 34.77 -0.006571 2017 5 8 2018-01-02 33.38 0.009069 2018 2 9 2018-01-03 33.76 0.011384 2018 3 10 2018-01-04 33.74 -0.000592 2018 4 11 2018-01-05 33.65 -0.002667 2018 5 12 2019-01-02 27.90 0.012704 2019 2 13 2019-01-03 28.18 0.010036 2019 3 14 2019-01-04 28.41 0.008162 2019 4 15 2019-01-07 28.26 -0.005280 2019 5

    我创建了一个 DataFrame,其中只有 tdoyperc 的 2019 年值

    df19 = df[['tdoy','perc']].loc[df['year'] == 2019]

    然后为这些值压缩字典 perc19 = dict(zip(df19.tdoy,df19.perc))

    结束

    perc19= {2: 0.012704174228675058, 3: 0.010035842293906852, 4: 0.008161816891412365, 5: -0.005279831045406497}

    然后将这些键与原始 DataFrame 中的 tdoy 列进行映射,以创建标题为 2019 的列,该列具有该交易日对应的 2019 年百分比变化值

    df['2019'] = df['tdoy'].map(perc19)

    然后创建一个vs2019 列,在其中我找到2019perc 的差异并将其平方产生

    Dates last perc year tdoy 2019 vs2019 0 2016-01-04 29.93 -0.020295 2016 2 0.012704 6.746876 1 2016-01-05 29.63 -0.010023 2016 3 0.010036 3.995038 2 2016-01-06 29.59 -0.001350 2016 4 0.008162 1.358162 3 2016-01-07 29.44 -0.005069 2016 5 -0.005280 0.001590 4 2017-01-03 34.57 0.004358 2017 2 0.012704 0.431608 5 2017-01-04 34.98 0.011860 2017 3 0.010036 0.033038 6 2017-01-05 35.00 0.000572 2017 4 0.008162 0.864802 7 2017-01-06 34.77 -0.006571 2017 5 -0.005280 0.059843 8 2018-01-02 33.38 0.009069 2018 2 0.012704 0.081880 9 2018-01-03 33.76 0.011384 2018 3 0.010036 0.018047 10 2018-01-04 33.74 -0.000592 2018 4 0.008162 1.150436

    从这里我可以通过各种方式进行分组,并进一步计算以找到与我比较的年份(2019 年)最相似的趋势百分比变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      相关资源
      最近更新 更多