在Jupyter Notebook中实现DataFrame自定义颜色列表循环迭代,适配任意唯一值数量
解决Jupyter Notebook中DataFrame自定义颜色循环分配的问题
我明白你遇到的困扰了——当目标列的唯一值数量超过自定义颜色列表长度时,原代码因为会逐个消耗颜色元素,直接把列表掏空,自然会触发索引越界错误。要实现颜色的循环迭代,核心思路就是复用颜色列表而非消耗它,用索引取模的方式就能轻松解决这个问题。
核心修改点
- 不再从
colors_to_use中删除元素,而是通过索引 % 颜色列表长度的方式循环获取颜色 - 用
enumerate遍历唯一值,既能拿到每个唯一值,又能获取它的顺序索引,方便匹配循环颜色
修正后的完整代码
import pandas as pd df1 = pd.DataFrame({'x1':['a', 'b', 'b', 'c', 'd', 'd'], 'x2':['3', '4', '8', '0', '11', '1']}) df2 = pd.DataFrame({'x1':['a', 'a', 'c', 'd', 'e', 'e', 'f', 'g', 'g', 'g', 'h'], 'x2':['0', '41', '22', '5', '19', '21', '5', '7', '8', '24', '15']}) def Color_Unique(s): df = s.copy() color_map = {} unique_values = df['x1'].unique() colors_to_use = ['background-color: #ADD8E6', 'background-color: #90ee90', 'background-color: #FFD580', 'background-color: #CBC3E3', 'background-color: #D3D3D3', 'background-color: #C4A484'] color_count = len(colors_to_use) # 通过索引取模实现颜色循环分配 for idx, val in enumerate(unique_values): color_map[val] = colors_to_use[idx % color_count] # 为每行匹配对应颜色 for index, row in df.iterrows(): val = row['x1'] df.loc[index,:] = color_map.get(val, 'background-color: ') return df # 测试两个DataFrame df3 = df1.style.apply(Color_Unique, axis=None) display(df3) df4 = df2.style.apply(Color_Unique, axis=None) display(df4)
代码细节说明
idx % color_count:当唯一值的索引超过颜色列表长度时,取模运算会让索引自动回到起始位置,实现颜色的循环复用。比如第6个唯一值(索引5)对应最后一个颜色,第7个唯一值(索引6)就会匹配第一个颜色,以此循环。color_map.get(val, ...):使用字典的get方法更安全,即使意外遇到不在唯一值集合里的元素(理论上不会出现),也能返回默认的空背景色,避免触发KeyError。- 完全保留了你原代码的核心逻辑,只修改了颜色分配的方式,不管目标列有多少个唯一值,都能持续循环使用你的自定义颜色列表。
内容的提问来源于stack exchange,提问作者b_ham




