Python 将值预先添加到Panda';基于另一个数据帧的索引级别创建数据帧
下面我有两个数据帧。第一个数据帧(d1)具有“日期”索引,第二个数据帧(d2)具有“日期”和“名称”索引。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从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