从MultiIndex中删除级别

时间:2017-03-06 10:51:55

标签: python pandas dataframe

我需要从DataFrame的索引中删除一个级别(按位置或名称),并使用新索引创建一个新的DataFrame。问题是我最终得到了一个非唯一索引。

我看了Remove a level from a pandas MultiIndex,但问题是使用unique(),正如其中的答案所暗示的那样,减少了数组的索引,而不保留数组的名称。水平。

除了使用unique(),然后通过将标签名称拼接到数组上来创建新索引,是否有更优雅的解决方案?

index = [np.array(['foo', 'foo', 'qux']), np.array(['a', 'b', 'a'])]
data = np.random.randn(3, 2)
columns = ["X", "Y"]
df = pd.DataFrame(data, index=index, columns=columns)
df.index.names = ["Level0", "Level1"]
print df

                      X         Y
Level0 Level1                    
foo    a      -0.591649  0.831599
       b       0.049961 -1.524291
qux    a      -0.100124 -1.059195

index2 = df.reset_index(level=1, drop=True).index
df2 = pd.DataFrame(index=index2)
print df2.loc[idx['foo'], :]

Empty DataFrame
Columns: []
Index: [foo, foo]

1 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您正在寻找一种解决方案来获得没有重复值的第一级索引。您的结果应该是Ìndex对象,而不使用unique并且不再显式创建索引。

对于您的示例数据框,您可以使用以下内容,包括get_level_valuesdrop_duplicates

print(df.index.get_level_values(0).drop_duplicates())
Index(['foo', 'qux'], dtype='object', name='Level0')

修改

对于更一般的解决方案,要么根据级别数返回IndexMultiIndex,您可以结合使用dropleveldrop_duplicates

print(df.index.droplevel(-1).drop_duplicates())
Index(['foo', 'qux'], dtype='object', name='Level0')

以下是来自链接SO帖子的示例,其中3个级别被降低到2级mutltiindex并具有唯一值:

tuples = [(0, 100, 1000),(0, 100, 1001),(0, 100, 1002), (1, 101, 1001)]
index_3levels=pd.MultiIndex.from_tuples(tuples,names=["l1","l2","l3"])
print(index_3levels)

MultiIndex(levels=[[0, 1], [100, 101], [1000, 1001, 1002]],
           labels=[[0, 0, 0, 1], [0, 0, 0, 1], [0, 1, 2, 1]],
           names=['l1', 'l2', 'l3'])


index2level= index_3levels.droplevel(-1).drop_duplicates()
print(index2level)

MultiIndex(levels=[[0, 1], [100, 101]],
           labels=[[0, 1], [0, 1]],
           names=['l1', 'l2'])

# show unique values of new index
print(index2level)
[(0, 100) (1, 101)]