使用Scipy进行DataFrame层次聚类:按列还是按行?
关于Scipy层次聚类中行/列处理的疑问解答
首先直接给你明确答案:Scipy的层次聚类工具(比如scipy.cluster.hierarchy.linkage)默认是按行处理样本的——每一行代表一个待聚类的样本,每一列代表样本的一个特征。
接下来拆解你的疑问:
1. 转置DataFrame结果不同的原因
当你转置DataFrame后,原来的特征列变成了新的行(样本),原来的样本行变成了新的列(特征)。这时候聚类的对象完全变了:
- 原DataFrame(样本×特征):聚类的是样本(比如不同的用户、实验样品)
- 转置后(特征×样本):聚类的是特征(比如不同的指标、变量)
举个简单的代码例子:
import pandas as pd from scipy.cluster.hierarchy import linkage # 构造样本×特征的DataFrame df = pd.DataFrame({ 'feature1': [1, 2, 3], 'feature2': [4, 5, 6] }, index=['sample1', 'sample2', 'sample3']) # 聚类样本(行) sample_linkage = linkage(df) # 聚类特征(转置后的行) feature_linkage = linkage(df.T)
这两个linkage结果完全不同,因为它们聚类的对象根本不一样。
2. 所谓“按列聚类是标准做法”的误区
你听到的“标准做法”其实是分场景的:
- 如果你的目标是特征聚类(比如把相关性高的指标归为一类,简化后续分析),那确实需要转置后按原列(转置后的行)来聚类,这时候有人会说“按列做”;
- 如果目标是样本聚类(比如把相似的客户分组),那标准做法就是直接按行处理样本。
没有绝对的“必须按列”,核心是看你要聚类的是样本还是特征。
3. Scipy文档里的隐藏说明
其实Scipy的文档里是有明确说明的,只是可能你没留意到:在linkage函数的参数说明里,输入的二维数组y被定义为(n_samples, n_features)——也就是行是样本数,列是特征数。函数会默认计算样本之间的距离(行与行的距离),再进行聚类。
总结
判断是否需要转置,只需要想清楚:你要把哪些对象聚在一起?
- 聚样本 → 直接用原DataFrame(行=样本)
- 聚特征 → 转置DataFrame(转置后的行=原特征)
内容的提问来源于stack exchange,提问作者pyrifo
相关产品推荐
相关产品推荐

