Python 将值预先添加到Panda';基于另一个数据帧的索引级别创建数据帧

Python 将值预先添加到Panda';基于另一个数据帧的索引级别创建数据帧,python,numpy,pandas,Python,Numpy,Pandas,下面我有两个数据帧。第一个数据帧(d1)具有“日期”索引,第二个数据帧(d2)具有“日期”和“名称”索引。 您会注意到,d1从2014-04-30开始,d2从2014-01-31开始 d1: 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 n

下面我有两个数据帧。第一个数据帧(d1)具有“日期”索引,第二个数据帧(d2)具有“日期”和“名称”索引。
您会注意到,d1从2014-04-30开始,d2从2014-01-31开始

d1:

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

执行此操作的最有效或最简单的方法可能不是很优雅,但您的
df2
具有
多索引

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

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

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
[126]中的
:直接定义(d1,d2):
dates2=d2.index.get_level_值('Date')
dates1=d1.index
返回d1.reindex(dates2[dates2
如果您愿意为了性能牺牲一些可读性,您可以通过日期的内部表示(整数更快)来比较日期,并手动执行“回填”:

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
[129]中的
:def fast(d1,d2):
dates2=d2.index.get_level_值('Date')
dates1=d1.index
新日期=日期2[日期2.asi8
谢谢,这两个都是很好的解决方案。好奇的是,您将如何为多个列执行此操作。例如,如果d1有一个value1和value2列,您需要对这两个列进行反向填充?这两种解决方案对我来说都适用,就像一般的多列情况一样。
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