当一个值必须保持相同时,如何标准化浮点列表?

问题描述

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

list_a = [0.25,0.25,0.25]

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

list_a_changed = [0.25,0.75,0.25]

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

list_a_normalized = [0.083,0.083,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.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.0833333333]
print(normalize([0.25,0.45,0.05,0.10],2)) # [0.296875,0.534375,0.11875000000000001]

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

normalize([0.25,2) -> [0.0625,0.0625,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,2,0.75))
,

使用change_normalized项并使列表规范化:
re_normalize通过乘以正确的因子(这是一个与未更改项目的总和之比)来使列表规范化:


def change_normalized(lst,index,value):
    def touch(lst,value):
        lst[index] = value
    def re_normalize(lst,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,value)

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

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

# 1.0
print(sum(list_b))

此代码可以缩小为:

def change_normalized(lst,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)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...