import pandas as pd
import numpy as np
from string import ascii_lowercase
tidx = pd.date_range(end='2016-04-30', freq='M', periods=3)
tidx2 = tidx + pd.offsets.MonthBegin(-1) + pd.offsets.Day(15) + pd.offsets.BDay(-1)
np.random.seed([3,1415])
df1 = pd.DataFrame(np.random.rand(9, 1), columns=['Value'],
index=pd.MultiIndex.from_product([tidx, list(ascii_lowercase)[:3]]))
df2 = pd.DataFrame(np.random.rand(9, 1), columns=['Value'],
index=pd.MultiIndex.from_product([tidx2, list(ascii_lowercase)[:3]]))
我想用df2.index.levels[0]
df1.index.levels[0]
我做了什么:
df1.unstack().reindex(df2.unstack().index, method='ffill').stack()
看起来像:
Value
2016-02-29 a 0.757983
b 0.934829
c 0.831104
2016-03-31 a 0.879891
b 0.926879
c 0.721535
2016-04-30 a 0.117642
b 0.145906
c 0.199844
但是,这并没有推广到MultiIndex
超过2级。
reindex
索引的特定级别的一般方法是什么?
答案 0 :(得分:1)
编辑:新解决方案,可能更符合问题的精神:
def func(dfg):
return dfg.reset_index(level=1, drop=True).reindex(df1.index.levels[0], method='ffill')
df2.groupby(level=1).apply(func).swaplevel(i=0, j=1).sortlevel(0)
这个想法是像往常一样在重建索引之前按级别1进行分组。与之前的解决方案不同,这将执行基于时间的前向填充。
第二次修改:为了推广到多个级别,请将level=1
替换为:
level=list(range(1, df2.index.nlevels))
在两个函数调用中。
上一个回答:
我不知道这是否适用于所有情况,但在这种情况下,它会返回您想要的结果:
df2.index.set_levels(df1.index.get_level_values(0), level=0)
结果:
In [12]: df2
Out[12]:
Value
2016-02-29 a 0.757983
b 0.934829
c 0.831104
2016-03-31 a 0.879891
b 0.926879
c 0.721535
2016-04-30 a 0.117642
b 0.145906
c 0.199844