使用Numpy与硬编码进行规范化

时间:2015-05-10 04:36:46

标签: 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)/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))

输出:

[-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]

有人可以向我解释为什么这个代码在第二个例子中表现不同,但在其他两个例子中也是如此?

我在硬编码示例中做了什么错误吗? NumPy做了什么来结束[-1,1]?

2 个答案:

答案 0 :(得分:2)

在计算平均值时,您不能将数组中的数字转换为浮点数。这对于你的第二个或第三个输入来说不是问题,因为它们碰巧整齐地运作(如@abarnert所解释的),但由于第二个输入没有,并且仅由int组成,你最终计算出平均值当它应该是1.5时为1。这会传播,导致您与使用NumPy函数的结果不一致。

如果用这个替换计算均值的行,这会迫使Python使用浮动除法:

mean = sum(array) / float(len(array))

你最终会得到[-1,1]作为第二组输入的结果,就像NumPy一样。

答案 1 :(得分:2)

作为seaotternerd explains,您使用的是整数。在Python 2中(除非你from __future__ import division),将整数除以整数会得到一个整数。

那么,为什么三个都不错呢?好吧,看看价值观。在第一个中,总和为40,len为8,而40/8 = 5.而在第三个中,10/5 = 2.但在第二个中,3/2 = 1.5。这就是为什么当你进行整数除法时,只有那个得到了错误的答案。

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

作为旁注,如果您对采用浮动的平均值感兴趣,那么使用sum / div还有其他问题。例如,[1, 2, 1e200, -1e200]的平均值应该是0.75,但如果你只是sum / div,那么你将获得0。 (为什么?好吧,1 + 2 + 1e200 == 1e200。)你可能想看一个简单的统计库,即使你没有使用NumPy,也可以避免所有这些问题。在Python 3中(首先可以避免你的问题),stdlib中有一个名为statistics;在Python 2中,你必须转到PyPI。