Change one weight in a list and adjust all other weights accordingly so that the sum of the list is 1.0 again

Question:

I have a list of weights which all have a value range between 0.0 and 1.0. The sum of the values in list should be always 1.0.

Now I would like to write a function in which I can change one weight from the list by a certain value (positive or negative). The remaining weights of the lst should be adjusted evenly, so that the sum of the list result in 1.0 again at the end.

Example:

weights = [0.5, 0.2, 0.2, 0.1]

If I increase the second entry of the list by 0.3, the resulting list should look like this:

weights = [0.4, 0.5, 0.1, 0.0]

I’ve tried with the following function:

def change_weight(weights, index, value):
  result = []
  weight_to_change = weights[index] + value
  weights.pop(index)
  for i, weight in enumerate(weights):
    if i == index:
      result.append(weight_to_change)

    result.append(weight - value/len(weights))

  return result

This works perfectly for the example above:

weights = [0.5, 0.2, 0.2, 0.1]
print(change_weight(weights, 1, 0.3))
# like expected: [0.4, 0.5, 0.1, 0.0]

However, if I want to change the second weight about 0.5. The the last element of the list will get a negative value:

weights = [0.5, 0.2, 0.2, 0.1]
print(change_weight(weights, 1, 0.5))

results in [0.33, 0.7, 0.03, -0.07]

However, I do not want any negative values in the list. Such values should instead be set to 0.0 and the remainder added or subtracted evenly to the other values.

Does anyone have an idea how I can implement this?

Asked By: Freddy

||

Answers:

Here is a implementation of the idea of @RemiCuingnet :

def change_weight(weights, index, value):
    new_weight = weights[index] + value
    old_sum = sum(w for i,w in enumerate(weights) if i != index)
    new_weights = []
    for i,w in enumerate(weights):
        if i == index:
            new_weights.append(new_weight)
        else:
            new_weights.append(w*(1-new_weight)/old_sum)
    return new_weights

For example

print(change_weight([0.5, 0.2, 0.2, 0.1],1,.3))
print(change_weight([0.5, 0.2, 0.2, 0.1],1,.5))

Output:

[0.3125, 0.5, 0.12500000000000003, 0.06250000000000001]
[0.18750000000000006, 0.7, 0.07500000000000002, 0.03750000000000001]
Answered By: John Coleman
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.