pandas和numpy中std的结果不同

4

我试图从每一列中减去平均值并除以标准偏差。我使用了两种不同的方法(numeric_data1numeric_data2):

import pandas as pd
data = pd.read_csv("https://s3.amazonaws.com/demo-datasets/wine.csv")
numeric_data = data.drop("color", 1)
numeric_data1 = ((numeric_data - numeric_data.mean()) /
                 numeric_data.std())
numeric_data2 = ((numeric_data - np.mean(numeric_data, axis=0)) /
                 np.std(numeric_data, axis=0))

type(numeric_data1)  # -> pandas.core.frame.DataFrame
type(numeric_data2)  # -> pandas.core.frame.DataFrame

两个数据框都是Pandas数据框,它们应该有相同的结果。然而,我得到了不同的结果:

numeric_data2 == numeric_data1  # -> False

我认为问题源于numpy和pandas处理数字精度的方式:

numeric_data.mean() == np.mean(numeric_data, axis=0)      # -> True
numeric_data.std(axis=0) == np.std(numeric_data, axis=0)  # -> False

对于均值,numpy和pandas给出的结果是一样的,但是对于标准差,我得到了略微不同的结果。

我的评估是否正确,或者我犯了某些错误?


3
可能是计算每个pandas.DataFrame列的numpy.std?的重复问题。 - Cristian Ciupitu
1个回答

10

在计算标准差时,重要的是你是在估算整个人口的标准差还是在计算整个人口的标准差时使用了该人口的较小样本。

如果是较小样本,则需要使用所谓的样本标准差。事实证明,当你将平均值的平方差总和除以观测次数时,你得到的是一个有偏估计。我们通过除以观测次数减1来纠正这一点。对于样本标准差,我们使用参数ddof=1进行控制,而对于人口标准差,我们使用参数ddof=0进行控制。

事实上,如果样本量很大,这并不太重要。但你会看到一些小的差异。

在你的pandas.DataFrame.std调用中使用自由度参数:

import pandas as pd
data = pd.read_csv("https://s3.amazonaws.com/demo-datasets/wine.csv")
numeric_data = data.drop("color", 1)
numeric_data1 = ((numeric_data - numeric_data.mean()) /
                 numeric_data.std(ddof=0))  # <<<
numeric_data2 = ((numeric_data - np.mean(numeric_data, axis=0)) /
                 np.std(numeric_data, axis=0))

np.isclose(numeric_data1, numeric_data2).all()  # -> True

或者在np.std调用中:

import pandas as pd
data = pd.read_csv("https://s3.amazonaws.com/demo-datasets/wine.csv")
numeric_data = data.drop("color", 1)
numeric_data1 = ((numeric_data - numeric_data.mean()) /
                 numeric_data.std())
numeric_data2 = ((numeric_data - np.mean(numeric_data, axis=0)) /
                 np.std(numeric_data, axis=0, ddof=1))  # <<<

np.isclose(numeric_data1, numeric_data2).all()  # -> True

你能详细解释一下吗? - psimeson
1
查看 numpy.std 的文档,可以看到 ddof 默认值为零;而查看 pandas.DataFrame.std 的文档,则可以看到 ddof 默认值为一。 - Scott Boston
感谢@ScottBoston,我明白了。我之前不知道ddof的意思。 - psimeson
3
给你更多的解释。 - piRSquared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接