取下多指数熊猫DF的子集,用索引出乎意料的行为



i具有从多个数据流的许多重复中的数据,该数据流以多索引数据框(其中每个重复标记为例如['rep1', 'rep2', .., 'repN'](。我通常需要在这些重复范围内将较大数据框的子集(例如df.loc['rep5':'rep50', :](中。

我无法找出一种方法来做到这一点,而没有后续子集的索引,仍然可以从较大的数据段(即['rep1', 'rep2', .., 'repN'](中保留整个索引值的列表。

因此,对于简化的示例,给定以下DF:

dfs = [pd.DataFrame({'vals': range(3)}) for i in range(3)]
df = pd.concat(dfs, keys=['l1', 'l2', 'l3'])
df
      vals
l1 0     0
   1     1
   2     2
l2 0     0
   1     1
   2     2
l3 0     0
   1     1
   2     2

然后取一个子集:

subset = df.loc['l2':, :]
subset
      vals
l2 0     0
   1     1
   2     2
l3 0     0
   1     1
   2     2

查看子集的索引,原始'l1'索引仍然存在:

subset.index
MultiIndex(levels=[['l1', 'l2', 'l3'], [0, 1, 2]],
           labels=[[1, 1, 1, 2, 2, 2], [0, 1, 2, 0, 1, 2]

如果我重置该索引级别,则'l1'似乎消失了:

subset.reset_index(level=0)
    level_0 vals
0   l2  0
1   l2  1
2   l2  2
0   l3  0
1   l3  1
2   l3  2

,然后我可以将'level_0'作为索引重新放置,从本质上是我想实现的目标

subset.reset_index(level=0).set_index('level_0', append=True).reorder_levels([1, 0]).index
MultiIndex(levels=[['l2', 'l3'], [0, 1, 2]],
           labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]],
           names=['level_0', None])

但是,这显然是一条非常循环的路线。我想另一个选项是放下其他行,但是当尝试为多索引DF做一系列行时,我发现df.drop非常笨拙。

如果数据帧不是层次结构,则不会发生这种行为。例如:

df = pd.DataFrame({'vals': range(5)}, index=['a', 'b', 'c', 'd', 'e'])
df.index
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

,然后取子集

subset = df.loc[('b', 'c', 'd'),:]
subset.index
Index(['b', 'c', 'd'], dtype='object')

我尚不清楚为什么这会以这种方式行事。

我认为,您需要pd.multiindex.remove_unused_levels

subset.index.remove_unused_levels()

输出:

MultiIndex(levels=[['l2', 'l3'], [0, 1, 2]],
           labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]])

最新更新