如何将一列包含正负小数的数据归一化到特定范围

8

我有一个十进制数字列表,如下所示:

[-23.5, -12.7, -20.6, -11.3, -9.2, -4.5, 2, 8, 11, 15, 17, 21]

我需要将此列表规范化以适应范围[-5,5]
如何在Python中实现?


将一个值范围映射到另一个范围的方法 - PaulMcG
5个回答

14
获取输入的范围非常简单:

old_min = min(input)
old_range = max(input) - old_min

这里有一个棘手的部分。你可以用新范围乘以并用旧范围除以,但几乎可以保证顶桶中只会有一个值。你需要扩大输出范围,使得顶桶与其他所有桶的大小相同。

new_min = -5
new_range = 5 + 0.9999999999 - new_min
output = [floor((n - old_min) / old_range * new_range + new_min) for n in input]

为什么使用“魔数”0.9999999999?如果有人有一个范围[0,1],那该数字会是多少呢? - Nairum
@Nairum,正如我在答案中所解释的那样,“魔数”始终是相同的;意图是略低于1。由于输出是整数,任何小数部分都将丢失。对于范围[0,1],您不希望精确地缩放到范围[0,1.0],否则几乎所有输入都将转换为0。如果您改为缩放到[0,1.9999999999],则会获得更均匀的分布。 - Mark Ransom
@Nairum,感谢你让我再次查看这个答案,让我意识到有一个错误;输出范围(-1,1)映射到0,使得该桶比其他所有桶大两倍。 - Mark Ransom

4
>>> L = [-23.5, -12.7, -20.6, -11.3, -9.2, -4.5, 2, 8, 11, 15, 17, 21]
>>> normal = map(lambda x, r=float(L[-1] - L[0]): ((x - L[0]) / r)*10 - 5, L)
>>> normal
[-5.0, -2.5730337078651684, -4.348314606741574, -2.2584269662921352, -1.7865168539325844, -0.7303370786516856, 0.7303370786516847, 2.0786516853932575, 2.752808988764045, 3.6516853932584272, 4.101123595505618, 5.0]

1
original_vals = [-23.5, -12.7, -20.6, -11.3, -9.2, -4.5, 2, 8, 11, 15, 17, 21 ]

# get max absolute value
original_max = max([abs(val) for val in original_vals])

# normalize to desired range size
new_range_val = 5
normalized_vals = [float(val)/original_max * new_range_val for val in original_vals]

2
只是一个小点,max函数中不需要内部列表:max(abs(val) for val in original_vals) 也可以工作。 - Burhan Khalid
1
谢谢 - 使用生成器总是很好的选择!我也意识到最后一行容易出现零除错误,这对于基于范围的方法来说是一个优势。 - mdscruggs

0
假设您的列表已排序:
# Rough code
# Get the range of the list
r = float(l[-1] - l[0])
# Normalize
normal = map(lambda x: (x - l[0]) / r, l)

基本上,您想将列表的基数调整为不同的范围。这将使您的原始列表归一化为[0,1]


-4

保持简单:

>>> foo = [-23.5, -12.7, -20.6, -11.3, -9.2, -4.5, 2, 8, 11, 15, 17, 21]
>>> [i for i in foo if int(i) in range(-5, 5)]
[-4.5, 2]

另外,如果您希望结果仅为整数:

>>> [int(i) for i in foo if int(i) in range(-5, 5)]
[-4, 2]

@Cerin 不否认这可能是事实,但这个问题已经超过一年了,我的回答是在没有任何被采纳的答案或来自OP的反馈之前。没有必要再次唤起这个问题。 - timss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接