我注意到当使用pandas和numpy时,相关计算返回不同的值。
这是我的样本数据:
import numpy as np
import pandas as pd
import os
df = pd.DataFrame(
{"name": ["a", "b", "c", "d", "e", "f"],
"type": [float, float, float, float, float, float],
"value": [2.121,np.nan,21.131,30.4242,100.424, 22.4341],
"obs": [44, 55, 22, 77, 88, 33],
"num": [66, 23, 62, 63, 23, 12]}
)
相关计算:
pandas_corr = df.corr()
numeric_only_df = df.select_dtypes("number").dropna()
numpy_corr = pd.DataFrame(np.corrcoef(numeric_only_df, rowvar=False), columns=numeric_only_df.columns, index=numeric_only_df.columns)
结果:使用熊猫:
value obs num
value 1.000000 0.732365 -0.524068
obs 0.732365 1.000000 -0.138357
num -0.524068 -0.138357 1.000000
使用numpy:
value obs num
value 1.000000 0.732365 -0.524068
obs 0.732365 1.000000 -0.134928
num -0.524068 -0.134928 1.000000
有些值是相同的,但有些不同,我想知道是否有人知道为什么和什么会导致他们中的一些不同。
仅obs
与num
的相关系数不同。原因是使用pandas的结果使用索引为1的行,而使用numpy的结果则没有。
>>> df
name type value obs num
0 a <class 'float'> 2.1210 44 66
1 b <class 'float'> NaN 55 23
2 c <class 'float'> 21.1310 22 62
3 d <class 'float'> 30.4242 77 63
4 e <class 'float'> 100.4240 88 23
5 f <class 'float'> 22.4341 33 12
>>> numeric_only_df
value obs num
0 2.1210 44 66
2 21.1310 22 62
3 30.4242 77 63
4 100.4240 88 23
5 22.4341 33 12
请注意,对于obs
和num
之间的相关性,所述行包含相关信息-仅对于一个变量为value
的任何相关性无关。因此,给pandas的信息比numpy要多,而且pandas不会忽略这些信息。
你可以做两件事来验证我的陈述。
- 首先,查看
pd.corr
的源代码,以验证pandas没有不必要地丢失任何数据,并且它在底层使用np.corrcoef
,因此结果必须相同。 - 其次,您可以使用两种方法对没有上述行(即
df.iloc[df.index!=1,-3:]
)的数据计算相关系数,以查看它们都产生相同的结果
>>> df.iloc[df.index!=1,-3:].corr()
value obs num
value 1.000000 0.732365 -0.524068
obs 0.732365 1.000000 -0.134928
num -0.524068 -0.134928 1.000000
>>> np.corrcoef(df.iloc[df.index!=1,-3:], rowvar=False)
array([[ 1. , 0.73236541, -0.52406831],
[ 0.73236541, 1. , -0.13492801],
[-0.52406831, -0.13492801, 1. ]])