Pandas corr() 返回 NaN 的频率太高
Pandas corr() returning NaN too often
我正在尝试 运行 我认为应该是数据帧上的简单相关函数,但它在我认为不应该的地方返回 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 values"。由于每一列都有重叠的值,结果不应该都是非 NaN 吗?
有很好的讨论 and , but neither answered my question. I've tried the float64
idea discussed here,但也失败了。
@hellpanderr 的评论提出了一个很好的观点,我正在使用 0.22.0
奖金问题 - 我不是数学家,但是这个结果中 B 和 C 之间如何存在 1:1 相关性?
结果似乎是您使用的数据的人工产物。在你写的时候,NA
s 被忽略了,所以它基本上归结为:
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
那么,其余组合的 NA
是从哪里来的呢?
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
因此,在这里您最终每列也只有两个值。不同之处在于 B
和 C
列仅包含一个值 (100
),它给出的标准偏差为 0
:
df[['A', 'C']].dropna().std()
A 0.707107
C 0.000000
计算相关系数时,除以标准差,得到 NA
.
我正在尝试 运行 我认为应该是数据帧上的简单相关函数,但它在我认为不应该的地方返回 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 values"。由于每一列都有重叠的值,结果不应该都是非 NaN 吗?
有很好的讨论float64
idea discussed here,但也失败了。
@hellpanderr 的评论提出了一个很好的观点,我正在使用 0.22.0
奖金问题 - 我不是数学家,但是这个结果中 B 和 C 之间如何存在 1:1 相关性?
结果似乎是您使用的数据的人工产物。在你写的时候,NA
s 被忽略了,所以它基本上归结为:
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
那么,其余组合的 NA
是从哪里来的呢?
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
因此,在这里您最终每列也只有两个值。不同之处在于 B
和 C
列仅包含一个值 (100
),它给出的标准偏差为 0
:
df[['A', 'C']].dropna().std()
A 0.707107
C 0.000000
计算相关系数时,除以标准差,得到 NA
.