使用 Numpy 与硬编码进行规范化
Normalization using Numpy vs hard coded
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] 结束?
计算平均值时,您没有将数组中的数字转换为浮点数。对于您的第二个或第三个输入,这不是问题,因为它们恰好可以很好地计算出来(正如@abarnert 所解释的),但是由于第二个输入没有,并且完全由整数组成,您最终计算的平均值为1 应该是 1.5。这会传播,导致您与使用 NumPy 函数的结果不一致。
如果用此替换计算平均值的行,这会强制 Python 使用浮点除法:
mean = sum(array) / float(len(array))
你最终会得到 [-1, 1] 作为第二组输入的结果,就像 NumPy 一样。
作为 ,您使用的是整数。在 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 intermediate and return values are used for integer inputs"。而且,虽然我不确定这一点,但我猜他们是专门这样设计的,以避免这样的问题。
附带说明一下,如果您对采用浮点数的平均值感兴趣,那么仅使用 sum
/ div
还存在其他问题。例如,[1, 2, 1e200, -1e200]
的均值实际上应该是 0.75,但如果您只执行 sum
/ div
,您将得到 0
。 (为什么?好吧,1 + 2 + 1e200 == 1e200
。)您可能想要查看一个简单的统计库,即使您没有使用 NumPy,也可以避免所有这些问题。在 Python 3(一开始就可以避免你的问题)中,stdlib 中有一个,叫做 statistics
;在 Python 2,你必须去 PyPI。
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] 结束?
计算平均值时,您没有将数组中的数字转换为浮点数。对于您的第二个或第三个输入,这不是问题,因为它们恰好可以很好地计算出来(正如@abarnert 所解释的),但是由于第二个输入没有,并且完全由整数组成,您最终计算的平均值为1 应该是 1.5。这会传播,导致您与使用 NumPy 函数的结果不一致。
如果用此替换计算平均值的行,这会强制 Python 使用浮点除法:
mean = sum(array) / float(len(array))
你最终会得到 [-1, 1] 作为第二组输入的结果,就像 NumPy 一样。
作为 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 intermediate and return values are used for integer inputs"。而且,虽然我不确定这一点,但我猜他们是专门这样设计的,以避免这样的问题。
附带说明一下,如果您对采用浮点数的平均值感兴趣,那么仅使用 sum
/ div
还存在其他问题。例如,[1, 2, 1e200, -1e200]
的均值实际上应该是 0.75,但如果您只执行 sum
/ div
,您将得到 0
。 (为什么?好吧,1 + 2 + 1e200 == 1e200
。)您可能想要查看一个简单的统计库,即使您没有使用 NumPy,也可以避免所有这些问题。在 Python 3(一开始就可以避免你的问题)中,stdlib 中有一个,叫做 statistics
;在 Python 2,你必须去 PyPI。