如何对含十六进制颜色列的Pandas DataFrame进行颜色聚类?
基于相似颜色对Pandas DataFrame中的十六进制颜色列聚类
我有一个包含两列十六进制颜色值的Pandas DataFrame,想要根据颜色相似度对它们进行聚类。我觉得只需要一些简单的数学运算,但不知道从哪里开始。
示例数据集
import pandas as pd data = [['#f2f1eb','#000000'], ['#9ad9f4', '#ecebe8'], ['#9cd9f3', '#000000'], ['#e3c988', '#ecebe8'], ['#b02e39', '#b02e39']] df = pd.DataFrame(data, columns=['hex1', 'hex2'])
期望输出
| hex1 | hex2 | cluster1 | cluster2 |
|---|---|---|---|
| #f2f1eb | #000000 | 1 | 2 |
| #9ad9f4 | #ecebe8 | 3 | 1 |
| #9cd9f3 | #000000 | 3 | 2 |
| #e3c988 | #ecebe8 | 4 | 1 |
| #b02e39 | #b02e39 | 5 | 6 |
我尝试的代码
我尝试了以下代码,但觉得应该有更简洁、更符合Python风格的实现方式:
def hex_to_rgb(hex_val): return mcolors.to_rgb(hex_val) # Convert hex color codes to RGB values df['rgb1'] = df['hex1'].apply(hex_to_rgb) df['rgb0'] = df['hex2'].apply(hex_to_rgb) kmeans1 = KMeans(n_clusters=10).fit(df['hex1'].tolist()) kmeans0 = KMeans(n_clusters=10).fit(df['hex2'].tolist()) df['cluster1'] = kmeans1.labels_ df['cluster2'] = kmeans0.labels_
优化后的实现
原代码的核心问题是直接用十六进制字符串拟合KMeans——字符串无法用于数值聚类计算,必须转换成RGB(或Lab、HSV这类更贴合人眼颜色感知的色彩空间)。以下是更简洁、规范的实现:
import pandas as pd from sklearn.cluster import KMeans from matplotlib.colors import mcolors data = [['#f2f1eb','#000000'], ['#9ad9f4', '#ecebe8'], ['#9cd9f3', '#000000'], ['#e3c988', '#ecebe8'], ['#b02e39', '#b02e39']] df = pd.DataFrame(data, columns=['hex1', 'hex2']) def cluster_colors(hex_series, n_clusters=None): # 将十六进制颜色转为RGB数值数组 rgb_values = hex_series.apply(mcolors.to_rgb).tolist() # 自动确定聚类数(也可手动指定) if n_clusters is None: n_clusters = len(hex_series.unique()) # 拟合KMeans并返回从1开始的聚类标签(匹配示例输出格式) kmeans = KMeans(n_clusters=n_clusters, random_state=42).fit(rgb_values) return kmeans.labels_ + 1 # 批量生成两列的聚类标签 df[['cluster1', 'cluster2']] = df[['hex1', 'hex2']].apply(cluster_colors) print(df)
优化点说明
- 封装
cluster_colors函数,复用颜色转换与聚类逻辑,符合DRY原则 - 直接调用
mcolors.to_rgb,无需额外定义转换函数 - 使用RGB数值进行聚类,修正原代码的核心错误
- 设置
random_state保证聚类结果可复现 - 自动基于唯一颜色数确定聚类数,也可根据需求手动指定
n_clusters参数
内容的提问来源于stack exchange,提问作者SMar3552
相关产品推荐
相关产品推荐

