[英]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.