簡體   English   中英

如何將 pandas.MultiIndex 的級別拆分為兩個新級別?

[英]How do I split the level of a pandas.MultiIndex into two new levels?

我有一個pandas.MultiIndex ,我想在其中“拆分”其中一個級別:

例如:

level_1   level_2         
a1        b1/c1   
          b1/c2    
          b2/c1    

->

level_1   level_2_1  level_2_2 
a1        b1         c1     
                     c2     
          b2         c1     

什么是好的、有效的方法來做到這一點?

我知道的一種解決方案使用pd.MultiIndex.from_tuples

pd.MultiIndex.from_tuples([
    (x, y[0], y[1])
    for x, y in zip(
        index.get_level_values("level_1"),
        index.get_level_values("level_2").map(lambda x: x.split("/")).map(tuple)
    )],
    names=["level_1", "level_2_1", "level_2_2"]
)

但這太慢了。

最好的方法是什么?

不太確定您的確切用例,請分享有關您的輸入/輸出的更多詳細信息。 如果 MultiIndex 在索引上,我會嘗試類似下面的操作。

df.reset_index(inplace=True)
df[["level_2_1","level_2_2"]] = df["level_2"].str.split("/",expand=True)
df.drop(["level_2"],axis=1,inplace=True)
df.set_index(["level_1","level_2_1","level_2_2"])

希望能幫助到你!

您可以為MultiIndex使用數組構造函數或默認構造函數。 該過程將像這樣工作:

  • '/'上拆分索引'level_2'
  • 將舊索引中的'level_1'與拆分索引的每個部分組合起來。
  • 重建MultiIndex

首先讓我們構建一個Series & MultiIndex來使用:

import pandas as pd

index = pd.MultiIndex.from_product(
    [['a1'], ['b1/c1', 'b1/c2', 'b2/c1']], names=['level_1', 'level_2']
)
s = pd.Series(0, index=index)

print(s)
level_1  level_2
a1       b1/c1      0
         b1/c2      0
         b2/c1      0
dtype: int64

默認MultiIndex構造函數

我沒有為此計時,但我猜這將是性能最高的解決方案。

split_idx = s.index.get_level_values('level_2').str.split('/', expand=True)

# combine old/new indexes here
codes = [s.index.codes[0], *split_idx.codes]
levels = [s.index.levels[0], *split_idx.levels]
names = [s.index.names[0], *[f'level_2_{i}' for i in range(1, split_idx.nlevels+1)]]

new_index = pd.MultiIndex(codes=codes, levels=levels, names=names)

print(new_index)
MultiIndex([('a1', 'b1', 'c1'),
            ('a1', 'b1', 'c2'),
            ('a1', 'b2', 'c1')],
           names=['level_1', 'level_2_1', 'level_2_2'])

print(s.set_axis(new_index))
level_1  level_2_1  level_2_2
a1       b1         c1           0
                    c2           0
         b2         c1           0
dtype: int64

MultiIndex.from_arrays構造函數

這可能是一個更具可讀性的解決方案,因為from_arrays構造函數比默認構造函數更熟悉。

split_idx = index.get_level_values(1).str.split('/', expand=True)

# Build new index structure, seeded with the first level of the original Index
arrays = [s.index.get_level_values(0)]
names = [s.index.names[0]]
for level in range(split_idx.nlevels):
    arrays.append(split_idx.get_level_values(level))
    names.append(f'level_2_{level+1}')

new_index = pd.MultiIndex.from_arrays(arrays, names=names)

print(new_index)
MultiIndex([('a1', 'b1', 'c1'),
            ('a1', 'b1', 'c2'),
            ('a1', 'b2', 'c1')],
           names=['level_1', 'level_2_1', 'level_2_2'])

print(s.set_axis(new_index))
level_1  level_2_1  level_2_2
a1       b1         c1           0
                    c2           0
         b2         c1           0
dtype: int64

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM