Pandas 从另一个缺少日期的数据框返回最近三天的值

Pandas 从另一个缺少日期的数据框返回最近三天的值,pandas,Pandas,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

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
最初只有索引和obs_日期

目标

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

  • 上一个最近的交易日:如果在
    trade\u date
    中可以找到
    obs\u date
    ,它将返回相应的日期 pct_chg(例如2019/9/23:-0.9769)。如果没有,它将返回相应的最近一天pct chg(例如2019/9/21:0.2390、2019/10/5:-0.9201)
  • 最后一天pct chg:如果在
    trade\u date
    中可以找到
    obs\u date
    ,它将返回相应的最后一天pct chg(例如2019/9/24:0.2776)。如果没有,它将返回最近的对应最后一天pct chg(例如2019/10/5:0.1182、2019/9/23:NULL)
  • avg_l3d_pct_chg/max_l3d_pct_chg:基于
    obs_日期
    ,它返回最近3个
    trade_日期
    (例如2019/10/5、2019/9/26、9/27、9/30、2019/10/09、2019/10/09、10/8、9/30)的平均值或最大值
试试看


我考虑了这个。但是似乎不起作用。< /P> < P>可以根据“<代码> DF1 < /代码>创建四个<代码>系列/代码>,并在使用<代码> .SHIFT()<代码>之后,然后<代码>重采样('1D),将它们合并到您的<代码> DF2<代码>中。这四个系列是:

  • s0
    -直接将数据从df1合并到df2,从而产生一些
    NaN
  • s1
    -数据从df1到df2的合并,但使用
    ffill()
    ,因此如果
    NaN
    ,您可以获得前一天的数据
  • s2
    -将数据从df1合并到df2,但使用
    .shift(1)
    ffill()
    ,因此如果
    NaN
    ,您可以在前几天获得
    2
  • s3
    -将数据从df1合并到df2,但使用
    .shift(2)
    ffill()
    ,因此如果
    NaN
    ,您可以提前3天获得
  • 从这里,您可以导出
    平均值
    最大值
    ,以及操作
    1
    2
    'last\u recent\u day\u pct\u chg'
    last\u second\u day\u pct\u chg'
    ),然后重命名末尾的列,以保持其语法清晰,因为列名很长

    注意:对于您想要的
    'last\u recent\u day\u pct\u chg'
    'last\u second\u day\u pct\u chg'
    的输出是什么,有点混淆(我认为您的问题中可能有错误),但是如果输出不正确,您可以轻松地调整这两行

    df2[1] = np.where(df2[0].notnull(), df2[0], df2[1])
    df2[2] = np.where(df2[0].notnull(), df2[0], df2[2])
    
    完整代码:



    但如果df2中有重复的值,结果应该返回原始索引,该怎么办。@Jack df1会有重复的日期值吗?不会,但df2可能有重复的日期值values@Jack如果日期重复,它将正确返回,并且我已通过调整merge以在索引和列上使用
    df2=df2.merge(pd.concat)进行合并来包含原始索引([s0,s1,s2,s3],轴=1),右索引=True,左索引=obs\u date')
    而不是使用
    reset\u index()
    并在列和列上合并。
    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