Pandas corr() 过于频繁地返回 NaN

Posted

技术标签:

【中文标题】Pandas corr() 过于频繁地返回 NaN【英文标题】:Pandas corr() returning NaN too often 【发布时间】:2019-02-27 05:28:32 【问题描述】:

我正在尝试在数据帧上运行我认为应该是简单的相关函数,但它在我认为不应该的地方返回 NaN。

代码:

# setup
import pandas as pd
import io

csv = io.StringIO(u'''
id  date    num
A   2018-08-01  99
A   2018-08-02  50
A   2018-08-03  100
A   2018-08-04  100
A   2018-08-05  100
B   2018-07-31  500
B   2018-08-01  100
B   2018-08-02  100
B   2018-08-03  0
B   2018-08-05  100
B   2018-08-06  500
B   2018-08-07  500
B   2018-08-08  100
C   2018-08-01  100
C   2018-08-02  50
C   2018-08-03  100
C   2018-08-06  300
''')

df = pd.read_csv(csv, sep = '\t')

# Format manipulation
df = df[df['num'] > 50]
df = df.pivot(index = 'date', columns = 'id', values = 'num')
df = pd.DataFrame(df.to_records())

# Main correlation calculations
print df.iloc[:, 1:].corr()

主题数据框:

       A      B      C
0    NaN  500.0    NaN
1   99.0  100.0  100.0
2    NaN  100.0    NaN
3  100.0    NaN  100.0
4  100.0    NaN    NaN
5  100.0  100.0    NaN
6    NaN  500.0  300.0
7    NaN  500.0    NaN
8    NaN  100.0    NaN

corr() 结果:

    A    B    C
A  1.0  NaN  NaN
B  NaN  1.0  1.0
C  NaN  1.0  1.0

根据函数上的(有限)documentation,它应该排除“NA/null 值”。由于每一列都有重叠的值,结果不应该都是非NaN吗?

here 和 here 的讨论很好,但都没有回答我的问题。我尝试了float64 讨论的here 的想法,但也失败了。

@hellpanderr 的评论提出了一个很好的观点,我使用的是 0.22.0

额外问题 - 我不是数学家,但是在这个结果中 B 和 C 之间如何存在 1:1 的相关性?

【问题讨论】:

pandas=0.23.4 给我[[1.0, nan, 0.9998469895178864], [nan, 1.0, 0.9819805060619657], [0.9998469895178864, 0.9819805060619657, 1.0]] 我可能稍微调整了一下,我刚刚更新了代码(> 50 而不是> 10),结果与我发布的结果相同。不确定这是否会改变你的情况。 现在我得到了和你一样的结果。 如果您尝试使用 df.cov()[['C','B']] / df.std()[['C','B']].product() 手动执行此操作? 现在您正在进入我帖子的“我不是数学家”部分。真的不知道。在核心统计计算方面,我有点不知所措。 【参考方案1】:

结果似乎是您使用的数据的人工制品。在你写的时候,NAs 被忽略了,所以它基本上可以归结为:

df[['B', 'C']].dropna()

       B      C
1  100.0  100.0
6  500.0  300.0

因此,每列只剩下两个值用于计算,因此应该lead to to correlation coefficients of 1

df[['B', 'C']].dropna().corr()

     B    C
B  1.0  1.0
C  1.0  1.0

那么,对于其余的组合,NAs 来自哪里?

df[['A', 'B']].dropna()

       A      B
1   99.0  100.0
5  100.0  100.0


df[['A', 'C']].dropna()

       A      C
1   99.0  100.0
3  100.0  100.0

所以,同样在这里,您最终每列只有两个值。不同之处在于BC 列仅包含一个值(100),其标准差为0

df[['A', 'C']].dropna().std()

A    0.707107
C    0.000000

计算相关系数时,除以标准差,得到NA

【讨论】:

Cleb - 感谢您完成繁重的工作,我认为您在关于标准偏差的最后一部分中将其钉住了。接受。 @elPastor:很高兴我能帮上忙。我应该放一个简短的故障排除部分here 并参考您的问题。

以上是关于Pandas corr() 过于频繁地返回 NaN的主要内容,如果未能解决你的问题,请参考以下文章

Pandas .corr() 返回“__”

seaborn 热图显示轴标签,但当 df.corr 为 NaN 时没有值

有效地检查 Python / numpy / pandas 中的任意对象是不是为 NaN?

Pandas 内插返回的 NaN

当所有值都是 NaN 时,Pandas 重新采样以返回 NaN

重新索引系列返回 Pandas 中的 NaN