【问题标题】:Normalization using Numpy vs hard coded使用 Numpy 与硬编码进行标准化
【发布时间】:2015-07-20 18:46:49
【问题描述】:
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]?

【问题讨论】:

  • 最后一个示例与第一个示例有何不同?在这两种情况下,您都得到了相同(或非常接近)的数字,只是打印了不同的小数位数(当然,它们之间使用逗号与不使用逗号)。
  • 啊,对不起。我的意思是反过来,只有 [1, 2] 的例子不同。

标签: python numpy normalization


【解决方案1】:

作为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。

【讨论】:

    【解决方案2】:

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

    如果你用这个替换计算平均值的行,这会强制 Python 使用浮点除法:

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

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

    【讨论】:

    • 或者,如果您认为 int / int 应该只返回一个 float,您可以升级到 Python 3 或 from __future__ import division,然后代码就可以正常工作了。 :)
    • 不管怎样,核心问题是对的,但解释是错误的——他在所有三个示例中都使用了整数,而不仅仅是损坏的示例,他甚至在他的 NumPy 代码中使用了它们。
    • 哦,是的,你完全正确。我以某种方式查看了第一个和第三个示例的输出而不是输入。
    猜你喜欢
    • 2019-11-24
    • 2020-03-08
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多