Python 使用Numpy与硬编码的标准化

Python 使用Numpy与硬编码的标准化,python,numpy,normalization,Python,Numpy,Normalization,产出: import numpy as np import math def normalize(array): mean = sum(array) / len(array) deviation = [(float(element) - mean)**2 for element in array] std = math.sqrt(sum(deviation) / len(array)) normalized = [(float(element) - mean)/

产出:

import numpy as np
import math

def normalize(array):
    mean = sum(array) / len(array)
    deviation = [(float(element) - mean)**2 for element in array]
    std = math.sqrt(sum(deviation) / len(array))
    normalized = [(float(element) - mean)/std for element in array]

    numpy_normalized = (array - np.mean(array)) / np.std(array)

    print normalized
    print numpy_normalized
    print ""

normalize([2, 4, 4, 4, 5, 5, 7, 9])
normalize([1, 2])
normalize(range(5))
有人能给我解释一下为什么这段代码在第二个例子中表现不同,但在其他两个例子中表现相似吗


在硬编码的示例中,我是否做错了什么?NumPy如何得到[-1,1]?

在计算平均值时,您没有将数组中的数字转换为浮点数。对于第二个或第三个输入来说,这不是问题,因为它们的计算结果恰到好处(正如@abarnert所解释的),但由于第二个输入没有,并且完全由整数组成,因此当平均值应该为1.5时,您最终将其计算为1。这会通过传播,导致您与使用NumPy函数的结果不一致

如果将计算平均值的行替换为该行,这将迫使Python使用浮点除法:

[-1.5, -0.5, -0.5, -0.5, 0.0, 0.0, 1.0, 2.0]
[-1.5 -0.5 -0.5 -0.5  0.   0.   1.   2. ]

[0.0, 1.414213562373095]
[-1.  1.]

[-1.414213562373095, -0.7071067811865475, 0.0, 0.7071067811865475, 1.414213562373095]
[-1.41421356 -0.70710678  0.          0.70710678  1.41421356]
对于第二组输入,您最终将得到[-1,1],就像NumPy一样。

因为您使用的是整数。在Python2中(除非您从uuu future\uuuu import division中选择
),将一个整数除以一个整数得到一个整数

那么,为什么这三个都没有错呢?好吧,看看这些值。在第一个例子中,和是40,len是8,40/8=5。在第三种情况下,10/5=2。但在第二种情况下,3/2=1.5。这就是为什么当你做整数除法时,只有那个人得到了错误的答案

那么,为什么NumPy没有把第二个也弄错呢?NumPy不会将整数数组视为浮点数,而是将它们视为整数-
print np.array(array).dtype
,您将看到
int64
。然而,正如文档中所解释的,“浮点64中间值和返回值用于整数输入”。而且,虽然我不确定这一点,但我猜他们是专门为避免这样的问题而设计的



作为补充说明,如果您对计算浮点数的平均值感兴趣,那么仅使用
sum
/
div
还有其他问题。例如,
[1,2,1e200,-1e200]
的平均值应该是0.75,但是如果你只做
sum
/
div
,你会得到
0
。(为什么?嗯,
1+2+1e200==1e200
)你可能想看看一个简单的统计库,即使你没有使用NumPy,也可以避免所有这些问题。在Python3中(它本来可以避免您的问题),stdlib中有一个名为
statistics
;在Python 2中,您必须转到PyPI。

最后一个示例与第一个示例有何不同?在这两种情况下,你得到了相同(或非常接近)的数字,只是用不同的小数位数打印(当然,它们之间有逗号,而没有)。啊,对不起。我的意思是相反的,只有[1,2]示例不同。或者,如果您认为
int/int
应该只返回一个
float
,您可以升级到Python 3或
,从uuuu future\uuuuuuu导入部分
,然后代码就可以按编写的那样工作了。:)不管怎样,核心问题是对的,但解释是错的,他在所有三个例子中都使用整数,而不仅仅是坏的一个,他甚至在他的NumPy代码中使用它们。哦,是的,你完全正确。对于第一个和第三个示例,我不知怎么看的是输出,而不是输入。
mean = sum(array) / float(len(array))