2014-10-03 62 views
0

下面我有两个数据框。第一个数据帧(d1)有一个'Date'索引,第二个数据帧(d2)有一个'Date'和'Name'索引。
您会注意到d1从2014-04-30开始,d2从2014-01-31开始。根据另一个数据框的索引级别将值预先分配给Panda的数据框

D1:

  Value 
Date    
2014-04-30  1 
2014-05-31  2 
2014-06-30  3 
2014-07-31  4 
2014-08-31  5 
2014-09-30  6 
2014-10-31  7 

D2:

    Value 
Date  Name  
2014-01-31 n1  5 
2014-02-30 n1  6 
2014-03-30 n1  7 
2014-04-30 n1  8 
2014-05-31 n2  9 
2014-06-30 n2  3 
2014-07-31 n2  4 
2014-08-31 n2  5 
2014-09-30 n2  6 
2014-10-31 n2  7 

我想要做的就是前面加上从D2较早日期,但使用的第一个值从D1到填充的值的行前面的行。

结果应该是这样的:

  Value 
Date 
2014-01-31  1 
2014-02-30  1 
2014-03-30  1   
2014-04-30  1 
2014-05-31  2 
2014-06-30  3 
2014-07-31  4 
2014-08-31  5 
2014-09-30  6 
2014-10-31  7 

什么最有效的还是最简单的方式来使用pandas

回答

1

这是您的问题的直接表述,它已经相当快了:

In [126]: def direct(d1, d2): 
     dates2 = d2.index.get_level_values('Date') 
     dates1 = d1.index 
     return d1.reindex(dates2[dates2 < min(dates1)].append(dates1), method='bfill') 
    .....: 

In [127]: direct(d1, d2) 
Out[127]: 
      Value 
Date    
2014-01-31  1 
2014-02-28  1 
2014-03-30  1 
2014-04-30  1 
2014-05-31  2 
2014-06-30  3 
2014-07-31  4 
2014-08-31  5 
2014-09-30  6 
2014-10-31  7 

In [128]: %timeit direct(d1, d2) 
1000 loops, best of 3: 362 µs per loop 

如果你愿意牺牲一些可读性的表现,你可以通过他们的内部表示比较日期(整数更快),并做了“回填”手动:

In [129]: def fast(d1, d2): 
    dates2 = d2.index.get_level_values('Date')  
    dates1 = d1.index 
    new_dates = dates2[dates2.asi8 < min(dates1.asi8)] 
    new_index = new_dates.append(dates1) 
    new_values = np.concatenate((np.repeat(d1.values[:1], len(new_dates), axis=0), d1.values)) 
    return pd.DataFrame(new_values, index=new_index, columns=d1.columns, copy=False) 
    .....: 

In [130]: %timeit fast(d1, d2) 
1000 loops, best of 3: 213 µs per loop 
+0

感谢,两者都是很棒的解决好奇,你会怎么做这个多列。例如,如果d1有一个value1和value2列,这两个列需要回填? – mike01010 2014-10-05 18:26:40

+0

这两种解决方案对我来说都适用于一般多列的情况。 – immerrr 2014-10-06 06:02:44

1

也许不是很优雅做到这一点,但你的df2MultiIndex

df3 = pd.concat((df1, df2.reset_index().set_index('Date')), axis=1).fillna(method='backfill') 
df3.index.name = 'Date' 
print df3.set_index([df3.index, df3.Name], drop=True).icol([0]) 


       Value 
Date  Name  
2014-01-31 n1  1 
2014-02-30 n1  1 
2014-03-30 n1  1 
2014-04-30 n1  1 
2014-05-31 n2  2 
2014-06-30 n2  3 
2014-07-31 n2  4 
2014-08-31 n2  5 
2014-09-30 n2  6 
2014-10-31 n2  7 
相关问题