Python 正态分布的Numpy变换

Python 正态分布的Numpy变换,python,numpy,normalization,Python,Numpy,Normalization,我有一组数据。我检查了它是否为正态分布: import sys import scipy from scipy import stats from scipy.stats import mstats from scipy.stats import normaltest Data = [] for line in open(sys.argv[1]): line = line.strip() Data.append(float(line)) print scipy.stats.no

我有一组数据。我检查了它是否为正态分布:

import sys
import scipy
from scipy import stats
from scipy.stats import mstats
from scipy.stats import normaltest

Data = []
for line in open(sys.argv[1]):
    line = line.strip()
    Data.append(float(line))
print scipy.stats.normaltest(Data)
输出为:(36.444648754208075,1.2193968690198398e-08)

然后,我编写了一个小脚本来规范数据:

import sys
import numpy as np
fileopen = open(sys.argv[1])
UntransformedArray = []
for line in fileopen:
    line = float(line.strip())
    UntransformedArray.append(line)
TransformedArray = (UntransformedArray - np.mean(UntransformedArray)/np.std(UntransformedArray))
NewList = TransformedArray.tolist()
for i in NewList:
    print i
import sys
import scipy
from scipy import stats
from scipy.stats import boxcox

Data = [(float(line.strip())) for line in open(sys.argv[1])]
scipy.stats.boxcox(Data)
然后我用第一个脚本再次检查了正常性,结果是 (36.444648754209595,1.2193968690189117e-08)

…与之前的分数相同,且不是正态分布

我的剧本错了吗

另外,我应该提到的是,我的数据的平均值是0.056,数字范围是0.014到0.171(85次观察),我不确定这些数字是不是很小

未转换和转换数据的示例:

-2.13696814254
-2.11796814254
-2.14296814254
-2.12496814254
-2.15396814254
-2.15496814254
-2.14696814254
未翻译:

0.055
0.074
0.049
0.067
0.038
0.037
0.045
0.041
转换数据:

-2.13696814254
-2.11796814254
-2.14296814254
-2.12496814254
-2.15396814254
-2.15496814254
-2.14696814254
编辑1:

当我稍微编辑代码以说明括号位于错误位置时:

TransformedMean = (UntransformedArray - np.mean(UntransformedArray))
TransformedArray = (TransformedMean/np.std(UntransformedArray))
NewList = TransformedArray.tolist()
for i in NewList:
    print i
我得到的输出不同:

例如:

-0.0385683544143
0.705333390576
-0.273484694937
0.431264326632
-0.704164652563
-0.743317375984
但是,当我检查是否正常时: (36.444648754241328,1.2193968689995659e-08)

它仍然不是正态分布(并且仍然与其他时间的分数完全相同)

编辑2:

然后我尝试了一种不同的数据标准化方法:

import sys
import numpy as np
fileopen = open(sys.argv[1])
UntransformedArray = []
for line in fileopen:
    line = float(line.strip())
    UntransformedArray.append(line)
TransformedArray = (UntransformedArray - np.mean(UntransformedArray)/np.std(UntransformedArray))
NewList = TransformedArray.tolist()
for i in NewList:
    print i
import sys
import scipy
from scipy import stats
from scipy.stats import boxcox

Data = [(float(line.strip())) for line in open(sys.argv[1])]
scipy.stats.boxcox(Data)
我得到错误:TypeError:不支持**或pow()的操作数类型:'list'和'float'

编辑3:由于用户的评论,问题在于理解标准化值与标准化分布的区别

编辑代码:

import sys
import numpy as np

fileopen = open(sys.argv[1])
UntransformedArray = []
for line in fileopen:
    line = float(line.strip())
    UntransformedArray.append(line)

List1 =  np.log(UntransformedArray) 
for i in List1:
    print i
检查是否正常化: (4.0435072214905938,0.13242304287973003)

(在这种情况下有效,具体取决于数据的倾斜度)

编辑4:或使用BoxCox变换:

import sys
import scipy
from scipy import stats
from scipy.stats import boxcox
import numpy as np

Data = []
for line in open(sys.argv[1]):
    line = line.strip()
    Data.append(float(line))

data = scipy.stats.boxcox(np.array(Data))
for i in data[0]:
    print i

检查归一化:(2.9085877478631956,0.23356523218452238)

如预期,减去平均值并重新调整为单位方差不会改变分布的形状
normaltest
在这两种情况下正确返回相同的输出,告诉您数据不是正态分布的

正如预期的那样,减去平均值并重新调整为单位方差不会改变分布的形状
normaltest
在这两种情况下正确返回相同的输出,告诉您数据不是正态分布的

我同意托马斯的观点。但更准确地说:您正在标准化阵列的分布!这不会改变分布的形状!您可能希望使用numpy.histogram()函数来获得分布的印象


我认为你已经沦为双重使用“正常化”的牺牲品。一方面,规范化用于描述变量的标准化(在相同的尺度上获取变量-这就是您所做的)。另一方面,归一化用于描述改变概率分布形状的尝试(scipy.stats.normaltest()用于检查此类分布的形状)。尝试更正常地获得分布的一个简单策略是使用日志转换。log()可能在这里起作用,但前提是原始分布不太倾斜

我同意托马斯的观点。但更准确地说:您正在标准化阵列的分布!这不会改变分布的形状!您可能希望使用numpy.histogram()函数来获得分布的印象


我认为你已经沦为双重使用“正常化”的牺牲品。一方面,规范化用于描述变量的标准化(在相同的尺度上获取变量-这就是您所做的)。另一方面,归一化用于描述改变概率分布形状的尝试(scipy.stats.normaltest()用于检查此类分布的形状)。尝试更正常地获得分布的一个简单策略是使用日志转换。log()可能在这里起作用,但前提是原始分布不太倾斜

我遇到了同样的问题。我的数据和你的数据不一样,我必须把数据转换成正态分布。为了将数据转换为正常值,您应该通过不同的方法使用正常分数转换,如所述。您也可以使用。我编写了一个python代码,用于将元素列表更改为正态分布,如下所示:

X = [0.055, 0.074, 0.049, 0.067, 0.038, 0.037, 0.045, 0.041]

from scipy.stats import rankdata, norm

newX = norm.ppf(rankdata(x)/(len(x) + 1))
print(newX)

output:
[ 0.4307273   1.22064035  0.1397103   0.76470967 -0.76470967 -1.22064035
-0.1397103  -0.4307273 ]
通过Q-Q图可以看出,经过此转换后,新数据完全正常:

from scipy import stats
import matplotlib.pyplot as plt

ax4 = plt.subplot(111)
res = stats.probplot(newX, plot=plt)
plt.show()

我遇到了同样的问题。我的数据和你的数据不一样,我必须把数据转换成正态分布。为了将数据转换为正常值,您应该通过不同的方法使用正常分数转换,如所述。您也可以使用。我编写了一个python代码,用于将元素列表更改为正态分布,如下所示:

X = [0.055, 0.074, 0.049, 0.067, 0.038, 0.037, 0.045, 0.041]

from scipy.stats import rankdata, norm

newX = norm.ppf(rankdata(x)/(len(x) + 1))
print(newX)

output:
[ 0.4307273   1.22064035  0.1397103   0.76470967 -0.76470967 -1.22064035
-0.1397103  -0.4307273 ]
通过Q-Q图可以看出,经过此转换后,新数据完全正常:

from scipy import stats
import matplotlib.pyplot as plt

ax4 = plt.subplot(111)
res = stats.probplot(newX, plot=plt)
plt.show()

在TransformedArray计算中没有括号问题吗?(UntransformedArray-np.mean(UntransformedArray))/np.std(UntransformedArray)这就是我所拥有的:TransformedArray=(UntransformedArray-np.mean(UntransformedArray)/np.std(UntransformedArray)),它似乎毫无怨言地运行?括号没有错误吗?算术除法(/)的优先级与减法(-)的优先级不同。因此,您要除以平均值/std,然后才应用减法。我想你的括号放错地方了。谢谢。我稍微更改了脚本(请参见编辑)。检查正常脚本是否可能有问题?我问这个问题的原因是,现在我给了检查正常性脚本两个不同的列表(例如,我的原始转换输出,其中所有数字都以-2.XXX开头,在我的编辑中,其中的数字是例如0.43,-0.7等),我仍然从检查正常性脚本?Re中得到完全相同的输出
boxcox
:尝试
scipy.stats.boxcox(np.array(Data))