使用np.corrcoef计算相关系数时返回NaN的问题排查
问题原因及解决方法
为什么返回NaN?
你的数组第一列所有元素都是1,这列的方差为0。皮尔逊相关系数的计算公式中,分母是两个变量标准差的乘积,当其中一个变量的标准差为0时,会触发除以0的运算,最终返回NaN。
解决代码示例
方法一:循环处理,手动修正特殊情况
import numpy as np norm_array=np.array([[1, 133, 1, 5.73, 5.09, 11.12, 10.16, 3.38, 15, 3, 8, 7, 4, 5, 1, 6, 1, 2, 18, 12, 48], [1, 185, 0, 4.34, 3.66, 18.23, 14.91, 0, 21, 15, 11, 2, 4, 4, 5, 4, 9, 8, 27, 14, 47], [1, 133, 1, 5.92, 4.63, 9.66, 7.77, 7.18, 9, 20, 4, 11, 9, 1, 7, 5, 3, 7, 29, 1, 45], [1, 165, 1, 4.26, 4.57, 16.05, 16.21, 8.81, 17, 17, 5, 10, 7, 7, 6, 3, 8, 6, 29, 7, 40], [1, 48, 11, 7.13, 8.51, 15.43, 17.74, 11.49, 20, 14, 6, 12, 6, 7, 6, 8, 8, 6, 39, 16, 38]]) cor = [] f = norm_array[:, 0] # 第一列和自身的相关系数理论为1,手动添加 cor.append(1.0) for j in range(1, norm_array.shape[1]): s = norm_array[:, j] # 检查任一变量方差为0的情况 if np.isclose(np.var(f), 0) or np.isclose(np.var(s), 0): # 方差为0时相关系数无意义,可按需设为0或其他值 cor.append(0.0) else: corr_val = np.corrcoef(f.astype(np.float32), s.astype(np.float32))[0, 1] cor.append(corr_val) print(cor)
方法二:用整体相关系数矩阵简化操作
import numpy as np norm_array=np.array([[1, 133, 1, 5.73, 5.09, 11.12, 10.16, 3.38, 15, 3, 8, 7, 4, 5, 1, 6, 1, 2, 18, 12, 48], [1, 185, 0, 4.34, 3.66, 18.23, 14.91, 0, 21, 15, 11, 2, 4, 4, 5, 4, 9, 8, 27, 14, 47], [1, 133, 1, 5.92, 4.63, 9.66, 7.77, 7.18, 9, 20, 4, 11, 9, 1, 7, 5, 3, 7, 29, 1, 45], [1, 165, 1, 4.26, 4.57, 16.05, 16.21, 8.81, 17, 17, 5, 10, 7, 7, 6, 3, 8, 6, 29, 7, 40], [1, 48, 11, 7.13, 8.51, 15.43, 17.74, 11.49, 20, 14, 6, 12, 6, 7, 6, 8, 8, 6, 39, 16, 38]]) # rowvar=False表示每一列是一个变量 corr_matrix = np.corrcoef(norm_array, rowvar=False) # 取第一行即为第一列与所有列的相关系数 cor = corr_matrix[0, :].tolist() # 修正第一列与自身的相关系数(原结果为NaN,实际应为1) cor[0] = 1.0 print(cor)
补充说明
- 当变量方差为0时,说明该变量没有波动,皮尔逊相关系数无法衡量其与其他变量的线性相关性,返回NaN是合理的,你可以根据实际需求决定如何处理这类情况(比如设为0)。
- 方法二更高效,尤其当数组列数较多时,无需循环遍历每一列。
内容的提问来源于stack exchange,提问作者user19381782
相关产品推荐
相关产品推荐

