You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas df.corrwith计算透视表DF相关系数时返回异常NaN问题

Pandas 1.4.1 corrwith()返回NaN问题说明

问题现象

使用Pandas 1.4.1版本调用df.corrwith()计算两个DataFrame的相关系数时出现不符合预期的结果:形状完全相同的两个DataFrame,手动构造时计算结果正常,数据来自pd.pivot_table()生成的透视表时返回全NaN值,和手动计算结果不符。

复现场景

1. 正常场景

直接构造两个形状为(6,1)、列名均为rating的DataFrame,代码如下:

import pandas as pd
import numpy as np
aa  = np.arange(6,dtype='float64')
bb  = np.arange(6,dtype='float64')

dd1  = {'rating':aa}
dd2  = {'rating':bb}

df_1 = pd.DataFrame(dd1)
df_2 = pd.DataFrame(dd2)

print('output of corrwith = \n', df_1.corrwith(df_2,axis=0))
print('df_1.shape = ', df_1.shape)
print('df_2.shape = ', df_2.shape)
print('-'*80)

运行结果符合预期,返回rating列相关系数为1.0:

output of corrwith = 
 rating    1.0
dtype: float64
df_1.shape =  (6, 1)
df_2.shape =  (6, 1)

2. 异常场景

两个DataFrame形状和正常场景完全一致,唯一区别是数据来自pd.pivot_table()生成的透视表(经fillna(0)填充空值),分别取透视表两列得到df_4、df_5,代码如下:

import pandas as pd
import numpy as np
dd3 = {'user':  [1,2,1,2,3,4,5,1,2,6],
       'movie': [1,2,1,3,4,5,6,1,3,2],
       'rating':[1,2,1,5,4,3,3,2,1,5]
       }
df_3 = pd.DataFrame(dd3)

df_pivot = pd.pivot_table(df_3,index='user',columns='movie',values='rating').fillna(0)

print(df_pivot)
print('-'*80)

df_4 = df_pivot.iloc[:,[1]]
df_5 = df_pivot.iloc[:,[2]]

print('output of corrwith = \n', df_4.corrwith(df_5,axis=0))
print('df_4.shape = ', df_4.shape)
print('df_5.shape = ', df_5.shape)
print('-'*80)

运行后返回两个NaN值,手动计算两列相关系数实际约为0.2:

output of corrwith = 
 movie
2   NaN
3   NaN
dtype: float64
df_4.shape =  (6, 1)
df_5.shape =  (6, 1)

根本原因

这不是版本bug,是corrwith()的默认匹配规则和直觉预期不一致:
axis=0模式下,corrwith()是按列名对齐配对计算,不是按列的位置配对。

  • 正常场景中两个DataFrame的列名完全一致,都是rating,可以成功匹配到计算对,因此返回正确的相关系数1.0。
  • 透视表生成的df_pivot列名是movie字段的取值:df_4是切出来的第2列,列名为2;df_5是切出来的第3列,列名为3。两个DataFrame没有任何重名的列。
  • 函数匹配列时,df_4的列2在df_5中找不到同名列,df_5的列3在df_4中找不到同名列,没有可以计算的有效列对,自然返回全NaN。两个DataFrame形状一致不代表列名能匹配上,和数据来源是不是透视表也没有直接关系。

解决方法

如果需要按位置计算两列的相关系数,任选以下一种方式处理即可:

  • 方法1:将两个DataFrame的列名重命名为一致名称,再调用corrwith()
df_4.columns = ['target_col']
df_5.columns = ['target_col']
print(df_4.corrwith(df_5, axis=0))
  • 方法2:直接提取为Series对象计算相关系数,Series计算不依赖名称对齐
print(df_4.iloc[:,0].corr(df_5.iloc[:,0]))

两种方式都可以得到正确结果约0.208。

内容的提问来源于stack exchange,提问作者NNN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 19:48:28