【问题标题】:Remove a level from a MultiIndex从 MultiIndex 中删除一个级别
【发布时间】:2017-03-06 22:15:29
【问题描述】:

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

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

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

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]

【问题讨论】:

    标签: python pandas dataframe


    【解决方案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)]
    

    【讨论】:

    • 谢谢,但我想删除一个关卡。因此,如果我有一个包含三个级别的索引作为输入,我想将其减少到两个级别。
    猜你喜欢
    • 2023-03-25
    • 2020-09-16
    • 2013-01-22
    • 2014-04-19
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多