【问题标题】:Return the most recent three days of values from another dataframe with missing dates从另一个缺少日期的数据框中返回最近三天的值
【发布时间】:2021-02-13 11:27:06
【问题描述】:

df1

    trade_date  pct_chg
266 2019-09-20  0.2390
265 2019-09-23  -0.9769
264 2019-09-24  0.2776
263 2019-09-25  -1.0018
262 2019-09-26  -0.8914
261 2019-09-27  0.1182
260 2019-09-30  -0.9201
259 2019-10-08  0.2885
258 2019-10-09  0.3874
257 2019-10-10  0.7814

df2

        obs_date     last_recent_day_pct_chg  last_second_day_pct_chg  avg_l3d_pct_chg  max_l3d_pct_chg  
  a     2019/9/21   
  b     2019/9/22   
  c     2019/9/23   
  d     2019/9/24   
  e     2019/9/25   
  f     2019/9/26   
  g     2019/9/27   
  h     2019/9/28   
  i     2019/9/29   
  j     2019/9/30   
  k     2019/10/5   
  l     2019/10/8   
  m     2019/10/9
  n     2019/10/9
  o     2019/9/29   

注意:df2 原来只有 index 和 obs_date。

目标

我想根据df1 获取df2 列的值,如下所示:

  • last_recent_day_pct_chg : 如果obs_date 可以在trade_date 中找到,则返回对应的 pct_chg.(例如 2019/9/23:-0.9769)。如果没有,则返回对应的 last_recent_day pct_chg。(例如 2019/9/21: 0.2390 , 2019/10/5:-0.9201)。
  • last_second_day_pct_chg : 如果obs_date 可以在trade_date 中找到,则返回对应的最后一天pct_chg。(例如2019/9/24:0.2776)。如果没有,它将返回最近对应的last_second_day_pct_chg。(例如2019/ 10/5:0.1182,2019/9/23:空)。
  • avg_l3d_pct_chg/max_l3d_pct_chg:基于obs_date,返回最近3个trade_date的pct_chg的平均值或最大值。(例如2019/10/5、2019/9/26、9/27、9/30 , 2019/10/09, 2019/10/09,10/8, 9/30)

试试

我考虑shift method 和这个post。但它似乎不起作用。

【问题讨论】:

    标签: pandas


    【解决方案1】:

    您可以基于df1 创建四个series,然后在使用.shift()resample('1D') 之后将它们合并到您的df2 中。这四个系列是:

    1. s0 - 将数据从 df1 直接合并到 df2,从而产生一些 NaN 值。
    2. s1 - 从 df1 到 df2 的数据合并,但使用 ffill(),所以如果 NaN,你可以得到前一天。
    3. s2 - 从 df1 到 df2 的数据合并,但使用 .shift(1)ffill(),因此如果 NaN,您可以提前几天获得 2
    4. s3 - 从 df1 到 df2 的数据合并,但使用了 .shift(2)ffill(),因此如果 NaN,您可以提前几天获得 3

    从那里,您可以派生meanmax,以及操作12(分别为'last_recent_day_pct_chg''last_second_day_pct_chg'),然后将最后的列重命名为由于列名很长,因此在语法上保持简洁。

    注意:您希望 'last_recent_day_pct_chg''last_second_day_pct_chg' 的输出有点令人困惑(我认为您的预期输出可能在您的问题中有错误),但如果您可以轻松调整这两行输出不正确。

    df2[1] = np.where(df2[0].notnull(), df2[0], df2[1])
    df2[2] = np.where(df2[0].notnull(), df2[0], df2[2])
    

    完整代码:


    df1 = df1.rename({'trade_date' : 'obs_date'}, axis=1)
    df1['obs_date'], df2['obs_date'] = pd.to_datetime(df1['obs_date']), pd.to_datetime(df2['obs_date'])
    s = pd.Series(df1['pct_chg'].tolist(), df1['obs_date'])
    s0 = s.resample('1D').mean()
    s1 = s.resample('1D').mean().ffill()
    s2 = s.shift(1).resample('1D').mean().ffill()
    s3 = s.shift(2).resample('1D').mean().ffill()
    df2 = df2.merge(pd.concat([s0,s1,s2,s3], axis=1), right_index=True, left_on='obs_date')
    df2[3] = df2.iloc[:,2:5].mean(axis=1)
    df2[4] = df2.iloc[:,2:5].max(axis=1)
    df2[1] = np.where(df2[0].notnull(), df2[0], df2[1])
    df2[2] = np.where(df2[0].notnull(), df2[0], df2[2])
    df2 = df2.drop(0, axis=1).rename({1:'last_recent_day_pct_chg', 2:'last_second_day_pct_chg',
                                      3:'avg_l3d_pct_chg', 4:'max_l3d_pct_chg'}, axis=1)
    df2
    
    Out[1]: 
        obs_date  last_recent_day_pct_chg  last_second_day_pct_chg  \
    a 2019-09-21                   0.2390                      NaN   
    b 2019-09-22                   0.2390                      NaN   
    c 2019-09-23                  -0.9769                  -0.9769   
    d 2019-09-24                   0.2776                   0.2776   
    e 2019-09-25                  -1.0018                  -1.0018   
    f 2019-09-26                  -0.8914                  -0.8914   
    g 2019-09-27                   0.1182                   0.1182   
    h 2019-09-28                   0.1182                  -0.8914   
    i 2019-09-29                   0.1182                  -0.8914   
    o 2019-09-29                   0.1182                  -0.8914   
    j 2019-09-30                  -0.9201                  -0.9201   
    k 2019-10-05                  -0.9201                   0.1182   
    l 2019-10-08                   0.2885                   0.2885   
    m 2019-10-09                   0.3874                   0.3874   
    n 2019-10-09                   0.3874                   0.3874   
    
       avg_l3d_pct_chg  max_l3d_pct_chg  
    a         0.239000         0.239000  
    b         0.239000         0.239000  
    c        -0.368950         0.239000  
    d        -0.153433         0.277600  
    e        -0.567033         0.277600  
    f        -0.538533        -0.538533  
    g        -0.591667         0.118200  
    h        -0.591667         0.118200  
    i        -0.591667         0.118200  
    o        -0.591667         0.118200  
    j        -0.564433         0.118200  
    k        -0.564433         0.118200  
    l        -0.171133         0.288500  
    m        -0.081400         0.387400  
    n        -0.081400         0.387400  
    

    【讨论】:

    • 但是如果df2中有重复的值,结果应该返回原始索引。
    • @Jack df1 会有重复的日期值吗?
    • 否,但 df2 可能有重复的日期值
    • @Jack 如果重复日期,它会正确返回,并且我通过调整合并以在索引和列上与 df2 = df2.merge(pd.concat([s0,s1,s2,s3], axis=1), right_index=True, left_on='obs_date') 合并而不是使用 reset_index() 并在列和列上合并来包含原始索引.
    猜你喜欢
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 2017-07-30
    相关资源
    最近更新 更多