繁体   English   中英

当一个值必须保持不变时,如何规范化浮点数列表?

[英]How to normalize a list of floats when one value has to stay the same?

我有一个包含这些标准化值的列表

list_a = [0.25, 0.25, 0.25, 0.25]

现在我想将一个条目的值更改为另一个数字,比如0.75 这个数字是固定的,不应再更改。

list_a_changed = [0.25, 0.25, 0.75, 0.25]

为了仍然确保列表中所有值的总和为1 ,其余值需要为0.0833 所以我的清单必须是:

list_a_normalized = [0.083, 0.083, 0.75, 0.083]

这很容易确定是否所有值在初始列表中共享相同的百分比。 我可以做1 - 0.75 = 0.25 ,然后在剩余数字之间除以0.25 ,因为它们都占总和的相同百分比。

value_change = 0.75
remaining_value = 1 - value_change
divided_remaining_value = remaining_value / (len(list_a_changed) - 1)

list_a_normalized = [divided_remaining_value, divided_remaining_value, value_change, divided_remaining_value ]


但是如果原始列表是这样的,你会怎么做:

list_b = [0.25, 0.45, 0.20, 0.10]

我将一个值更改为0.05

list_b_changed = [0.25, 0.45, 0.05, 0.10]

您将如何计算其他数字的值必须是多少,以便它们各自保留剩余0.95的适当部分?

你可以

  • 计算remaining
  • 计算没有变化值的总数,得到它们没有变化值的相对比例
  • 将它们的值乘以剩余的值以将其考虑在内,然后除以相对总数以使它们与总数成比例
def normalize(values, index_not_change):
    remaining = 1 - values[index_not_change]
    total_except_remaining = sum(values) - values[index_not_change]
    return [(value * remaining / total_except_remaining if idx != index_not_change else value)
            for idx, value in enumerate(values)]

print(normalize([0.25, 0.25, 0.75, 0.25], 2)) # [0.0833333333, 0.0833333333, 0.75, 0.0833333333]
print(normalize([0.25, 0.45, 0.05, 0.10], 2)) # [0.296875, 0.534375, 0.05, 0.11875000000000001]

要了解total_except_remaining目的,如果没有它,那就是

normalize([0.25, 0.25, 0.75, 0.25], 2) -> [0.0625, 0.0625, 0.75, 0.0625]

因为你已经计算了剩余的四分之一( 0.25 ),但加上相对总和是0.75而不是 1 的事实,你更新到它们的实际比例


你也可以用同样的方法进行修改

def normalize(values, position, new_value):
    values[position] = new_value
    remaining = 1 - new_value
    total_except_remaining = sum(values) - new_value
    return [(value * remaining / total_except_remaining if idx != position else value)
            for idx, value in enumerate(values)]

print(normalize([0.25, 0.25, 0.25, 0.25], 2, 0.75))

使用change_normalized项并保持列表规范化:
re_normalize通过乘以正确的因子(即 1 与没有更改项的总和之间的比率)使列表保持规范化:


def change_normalized(lst, index, value):
    def touch(lst, index, value):
        lst[index] = value
    def re_normalize(lst, index, value):
        multiply_factor = (1 - value) / (sum(lst) - value)
        for j in range(len(lst)):
            if i == j:
                continue
            lst[j] *= multiply_factor
    touch(lst, i, value)
    re_normalize(lst, i, value)

i = 2
value = 0.05
list_b = [0.25, 0.45, 0.20, 0.10]

# Change item at index to value and keep list normalized
change_normalized(list_b, i, value)

# 1.0
print(sum(list_b))

这段代码可以缩小为:

def change_normalized(lst, index, value):
    lst[index] = value
    multiply_factor = (1 - value) / (sum(lst) - value)
    lst[:] = [multiply_factor * x if i != j else x for j, x in enumerate(lst)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM