[英]Assigning values to Pandas Multiindex DataFrame by index level
[英]Replace singular value on second level of pandas dataframe multiindex when that index level has identical values
我有一個 dataframe,它有一個具有兩個級別的多索引。 給定第二級的以下示例:
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)
Output:
>>> 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 有點奇怪。 它們存儲為級別列表(包含唯一的label 值)和代碼(它們是標簽的索引)。 例如,您當前的 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'
字符串。 它的重復由代碼定義。
因此,如果你想通過操作級別和代碼將第二級別的第一個 label 設置為example
,你可能會像這樣 go :
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'
這是一個 function,您可以使用它來設置 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
這是另一個 function (使用前一個),您可以使用它來設置 MultiIndex 特定級別的特定 label (這是您的問題):
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.