当索引级别具有相同的值时,替换 pandas 数据帧多索引的第二级别上的奇异值
Replace singular value on second level of pandas dataframe multiindex when that index level has identical values
我有一个具有两个级别的多索引的数据框。给出第二级的以下示例:
d = {
"col1": [1, 2, 3, 4],
"col2": [1, 2, 3, 4],
"col3": [1, 2, 3, 4],
"col4": [1, 2, 3, 4],
"col5": [1, 2, 3, 4],
}
df = pd.DataFrame(data=d)
df.columns = pd.MultiIndex.from_product([df.columns, ["identical"]])
如何更改奇异值以使索引的第二级看起来像这样?
['example', 'identical', 'identical', 'identical', 'identical']
我试过这样做:
updated_columns = list(df.columns.get_level_values(1))
updated_columns[0] = 'example'
df.columns.set_levels(
updated_columns, level=1, inplace=True, verify_integrity=False
)
在这种情况下,我的更改将被忽略。
我也试过这个话题的答案:pandas MultiIndex with duplicate values in one level
df.columns = pd.MultiIndex.from_tuples(
df.columns.set_levels(updated_columns, 1, verify_integrity=False).values
)
也被忽略了。
我也考虑过使用 rename() 方法。不幸的是,它仅在提供重命名列的值时才有效。鉴于存在相同的值,这将不起作用。
对于非多索引有这个方法:
df.columns.values[0] = 'example'
但据我所知,它不适用于多索引。
我添加了 verify_integrity=False,因为该方法不允许我设置相同的值。
如有任何帮助,我们将不胜感激。
一种方法是获取构成 MultiIndex 的元组并直接修改它们:
tuples = df.columns.tolist()
tuples[0] = (tuples[0][0], 'example')
df.columns = pd.MultiIndex.from_tuples(tuples)
输出:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
MultiIndexes 有点奇怪。它们存储为级别列表(其中包含 unique 标签值)和代码(标签的索引)。例如,您当前的 MultiIndex 的级别和代码如下所示:
>>> df.columns.levels
FrozenList([['col1', 'col2', 'col3', 'col4', 'col5'], ['identical']])
>>> df.columns.codes
FrozenList([[0, 1, 2, 3, 4], [0, 0, 0, 0, 0]])
如您所见,那里只有一个 'indentical'
字符串。它的重复由代码定义。
所以如果你想通过操作级别和代码将第二级别的第一个标签设置为example
,你可以这样做:
vals = df.columns.levels[1].tolist()
vals.append('example')
df.columns = df.columns.set_levels(vals, level=1)
df.columns = df.columns.set_codes([1, 0, 0, 0, 0], level=1) # 1 = 'example', 2 = 'identical'
这是一个函数,您可以使用它来设置 MultiIndex 特定级别的所有标签:
def set_level_of_df(df, level_index, labels):
new_df = df.copy()
unique, inverse = np.unique(labels, return_inverse=True)
new_df.columns = new_df.columns.set_levels(unique, level=level_index)
new_df.columns = new_df.columns.set_codes(inverse, level=level_index)
return new_df
用法:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
>>> df = set_level_of_df(df, level_index=0, labels=['aaa', 'abc', 'xyz', '0123', '-----'])
>>> df
aaa abc xyz 0123 -----
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
这是另一个函数(使用前一个函数),您可以使用它来设置 MultiIndex 特定级别的特定标签(这是您的问题):
def set_label_of_label_of_df(df, level_index, label_index, label):
new_df = df.copy()
labels = df.columns.get_level_values(level=level_index).tolist()
labels[label_index] = label
return set_level_of_df(df, level_index, labels)
用法:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
>>> df = set_label_of_label_of_df(df, level_index=1, label_index=3, label='THIS_IS_A_TEST_VALUE')
>>> df
col1 col2 col3 col4 col5
example identical identical THIS_IS_A_TEST_VALUE identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
我有一个具有两个级别的多索引的数据框。给出第二级的以下示例:
d = {
"col1": [1, 2, 3, 4],
"col2": [1, 2, 3, 4],
"col3": [1, 2, 3, 4],
"col4": [1, 2, 3, 4],
"col5": [1, 2, 3, 4],
}
df = pd.DataFrame(data=d)
df.columns = pd.MultiIndex.from_product([df.columns, ["identical"]])
如何更改奇异值以使索引的第二级看起来像这样?
['example', 'identical', 'identical', 'identical', 'identical']
我试过这样做:
updated_columns = list(df.columns.get_level_values(1))
updated_columns[0] = 'example'
df.columns.set_levels(
updated_columns, level=1, inplace=True, verify_integrity=False
)
在这种情况下,我的更改将被忽略。
我也试过这个话题的答案:pandas MultiIndex with duplicate values in one level
df.columns = pd.MultiIndex.from_tuples(
df.columns.set_levels(updated_columns, 1, verify_integrity=False).values
)
也被忽略了。
我也考虑过使用 rename() 方法。不幸的是,它仅在提供重命名列的值时才有效。鉴于存在相同的值,这将不起作用。
对于非多索引有这个方法:
df.columns.values[0] = 'example'
但据我所知,它不适用于多索引。
我添加了 verify_integrity=False,因为该方法不允许我设置相同的值。
如有任何帮助,我们将不胜感激。
一种方法是获取构成 MultiIndex 的元组并直接修改它们:
tuples = df.columns.tolist()
tuples[0] = (tuples[0][0], 'example')
df.columns = pd.MultiIndex.from_tuples(tuples)
输出:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
MultiIndexes 有点奇怪。它们存储为级别列表(其中包含 unique 标签值)和代码(标签的索引)。例如,您当前的 MultiIndex 的级别和代码如下所示:
>>> df.columns.levels
FrozenList([['col1', 'col2', 'col3', 'col4', 'col5'], ['identical']])
>>> df.columns.codes
FrozenList([[0, 1, 2, 3, 4], [0, 0, 0, 0, 0]])
如您所见,那里只有一个 'indentical'
字符串。它的重复由代码定义。
所以如果你想通过操作级别和代码将第二级别的第一个标签设置为example
,你可以这样做:
vals = df.columns.levels[1].tolist()
vals.append('example')
df.columns = df.columns.set_levels(vals, level=1)
df.columns = df.columns.set_codes([1, 0, 0, 0, 0], level=1) # 1 = 'example', 2 = 'identical'
这是一个函数,您可以使用它来设置 MultiIndex 特定级别的所有标签:
def set_level_of_df(df, level_index, labels):
new_df = df.copy()
unique, inverse = np.unique(labels, return_inverse=True)
new_df.columns = new_df.columns.set_levels(unique, level=level_index)
new_df.columns = new_df.columns.set_codes(inverse, level=level_index)
return new_df
用法:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
>>> df = set_level_of_df(df, level_index=0, labels=['aaa', 'abc', 'xyz', '0123', '-----'])
>>> df
aaa abc xyz 0123 -----
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
这是另一个函数(使用前一个函数),您可以使用它来设置 MultiIndex 特定级别的特定标签(这是您的问题):
def set_label_of_label_of_df(df, level_index, label_index, label):
new_df = df.copy()
labels = df.columns.get_level_values(level=level_index).tolist()
labels[label_index] = label
return set_level_of_df(df, level_index, labels)
用法:
>>> df
col1 col2 col3 col4 col5
example identical identical identical identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4
>>> df = set_label_of_label_of_df(df, level_index=1, label_index=3, label='THIS_IS_A_TEST_VALUE')
>>> df
col1 col2 col3 col4 col5
example identical identical THIS_IS_A_TEST_VALUE identical
0 1 1 1 1 1
1 2 2 2 2 2
2 3 3 3 3 3
3 4 4 4 4 4