使用 Pandas 重命名查找字典中的多索引行
Renaming multiindex row from a look up dictionary with Pandas
鉴于当前演示文稿中所示的多级行,我想根据存储在查找字典中的信息重命名第一级索引。
目前,我想转置 df
并循环到现在的 column
名称。此后,将根据字典中存储的信息检查并重命名合适的新列名(即str_dic)。
但是,我想知道是否有更直接的做法?
草拟的代码如下
import pandas as pd
def create_df (idx):
df = pd.DataFrame ( {'A': [11, 21, 31],
'B': [12, 22, 32],
'C': [13, 23, 33]},
index=['ONE', 'TWO', 'THREE'] )
df.columns = pd.MultiIndex.from_product ( [['level1'], ['level2'], df.columns] )
df = df.set_index ( [[f'idx_{idx}'] * len ( df )], append=True ).swaplevel ( 0 )
# df = df.set_index ( [['temp_general'] * len ( df )], append=True ).swaplevel ( 0 )
return df
#look up dict
str_g = ['idx_0', 'idx_1', 'idx_2', 'idx_3','idx_4']
str_h = ['E', 'b', 'c', 'd','e']
str_dic = {str_g [i]: str_h [i] for i in range ( len ( str_g ) )}
# create the df
all_df = [create_df ( idx ) for idx in range ( 0, len(str_h)-1)] # Delibarately minus one for worse case scenario
df = pd.concat ( all_df, axis=0 )
df=df.T
all_ls=list(df.columns.values.tolist())
for xss in all_ls:
df=df.rename ( columns={xss: str_dic[xss[0]]}, level=1) #WIP
当前演示文稿
level1
level2
A B C
idx_0 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_1 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_2 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_3 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
预期输出
level1
level2
A B C
a ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
#######################
奖金:
根据 的建议,我们如何根据另一个查找字典在最高级别上附加另一个级别。
天真地,我会提出这样的建议
df.index = pd.MultiIndex.from_product ( [s1, df.index.get_level_values ( 0 ).unique (),
df.index.get_level_values ( 1 ).unique ()] )
但它return一个错误
ValueError: Length mismatch: Expected axis has 12 elements, new values
have 48 elements
基于Anurag修改的失败提议:
str_global=['typ1','typ1','typ2','typ2','typ3']
global_dic = {str_h [i]: str_global [i] for i in range ( len ( str_h ) )}
s1 = [global_dic.get ( x ) for x in df.index.get_level_values ( 0 ).unique ()]
df.index = pd.MultiIndex.from_product ( [s1, df.index.get_level_values ( 0 ).unique (),
df.index.get_level_values ( 1 ).unique ()] )
预期输出
A B C
typ1 E ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ1 b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ2 c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ2 d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
让我们尝试使用列表理解将 'level 0' 索引中 str_dic 的键替换为它们的值,然后使用 pd.MultiIndex.from_product()
生成一个 MultiIndex 并将其设置为等于数据帧的索引通过使用 index
属性::
s=[str_dic.get(x) for x in df.index.get_level_values(0).unique()]
df.index=pd.MultiIndex.from_product([s,df.index.get_level_values(1).unique()])
更新:
因为现在你有 4 个唯一的 level0 值和 3 个唯一的 level0 索引以及 s1 中的 4 个值所以 pd.MultiIndex.from_product()
创建 48 对 MultiIndex 所以它在那种情况下没有用所以使用:
s1=[global_dic.get(x) for x in df.index.get_level_values(0)]
df=df.set_index(pd.Series(s1).values,append=True)
df.index=df.index.reorder_levels([2,0,1])
df
的输出:
level1
level2
A B C
E ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
鉴于当前演示文稿中所示的多级行,我想根据存储在查找字典中的信息重命名第一级索引。
目前,我想转置 df
并循环到现在的 column
名称。此后,将根据字典中存储的信息检查并重命名合适的新列名(即str_dic)。
但是,我想知道是否有更直接的做法?
草拟的代码如下
import pandas as pd
def create_df (idx):
df = pd.DataFrame ( {'A': [11, 21, 31],
'B': [12, 22, 32],
'C': [13, 23, 33]},
index=['ONE', 'TWO', 'THREE'] )
df.columns = pd.MultiIndex.from_product ( [['level1'], ['level2'], df.columns] )
df = df.set_index ( [[f'idx_{idx}'] * len ( df )], append=True ).swaplevel ( 0 )
# df = df.set_index ( [['temp_general'] * len ( df )], append=True ).swaplevel ( 0 )
return df
#look up dict
str_g = ['idx_0', 'idx_1', 'idx_2', 'idx_3','idx_4']
str_h = ['E', 'b', 'c', 'd','e']
str_dic = {str_g [i]: str_h [i] for i in range ( len ( str_g ) )}
# create the df
all_df = [create_df ( idx ) for idx in range ( 0, len(str_h)-1)] # Delibarately minus one for worse case scenario
df = pd.concat ( all_df, axis=0 )
df=df.T
all_ls=list(df.columns.values.tolist())
for xss in all_ls:
df=df.rename ( columns={xss: str_dic[xss[0]]}, level=1) #WIP
当前演示文稿
level1
level2
A B C
idx_0 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_1 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_2 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
idx_3 ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
预期输出
level1
level2
A B C
a ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
#######################
奖金:
根据
天真地,我会提出这样的建议
df.index = pd.MultiIndex.from_product ( [s1, df.index.get_level_values ( 0 ).unique (),
df.index.get_level_values ( 1 ).unique ()] )
但它return一个错误
ValueError: Length mismatch: Expected axis has 12 elements, new values have 48 elements
基于Anurag修改的失败提议:
str_global=['typ1','typ1','typ2','typ2','typ3']
global_dic = {str_h [i]: str_global [i] for i in range ( len ( str_h ) )}
s1 = [global_dic.get ( x ) for x in df.index.get_level_values ( 0 ).unique ()]
df.index = pd.MultiIndex.from_product ( [s1, df.index.get_level_values ( 0 ).unique (),
df.index.get_level_values ( 1 ).unique ()] )
预期输出
A B C
typ1 E ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ1 b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ2 c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
typ2 d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
让我们尝试使用列表理解将 'level 0' 索引中 str_dic 的键替换为它们的值,然后使用 pd.MultiIndex.from_product()
生成一个 MultiIndex 并将其设置为等于数据帧的索引通过使用 index
属性::
s=[str_dic.get(x) for x in df.index.get_level_values(0).unique()]
df.index=pd.MultiIndex.from_product([s,df.index.get_level_values(1).unique()])
更新:
因为现在你有 4 个唯一的 level0 值和 3 个唯一的 level0 索引以及 s1 中的 4 个值所以 pd.MultiIndex.from_product()
创建 48 对 MultiIndex 所以它在那种情况下没有用所以使用:
s1=[global_dic.get(x) for x in df.index.get_level_values(0)]
df=df.set_index(pd.Series(s1).values,append=True)
df.index=df.index.reorder_levels([2,0,1])
df
的输出:
level1
level2
A B C
E ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
b ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
c ONE 11 12 13
TWO 21 22 23
THREE 31 32 33
d ONE 11 12 13
TWO 21 22 23
THREE 31 32 33