Home > Enterprise >  Calculate the prorata weight of a list of numbers (including negative) in Python
Calculate the prorata weight of a list of numbers (including negative) in Python

Time:06-17

I am looking for a way to distribute a positive number proportionally to a list of numbers based on their value (higher gets more). Think of it as distributing a fixed bonus amount based on everyone's performance (pnl).

This is simple if the numbers are all positive. The prorata weight of [1,2,3] would be [1/6, 2/6, 3/6]. But I am not sure how to handle the case for something like [-1, 2, 3] in code?

CodePudding user response:

well you'd need to define the weight for negative numbers, the most intuitive way to me would be to take their absolute value over the sum of the abs., something like :

total_sum = sum([abs(x) for x in my_list])
weights = [abs(x)/total_sum for x in my_list]

but this is just one way to do it, without more information on what you're trying to achieve it's hard to be more precise.

CodePudding user response:

In the absence of additional information: if the weights for [1,2,3] are [1/6, 2/6, 3/6], then for [-1,2,3] they would be [-1/4, 2/4, 3/4].

Example:

def get_weights(p, nums):
    total = sum(nums)
    return [p * num / total for num in nums]
    
print(get_weights(1, [1, 2, 3]))
print(get_weights(1, [-1, 2, 3]))

Output:

[0.16666666666666666, 0.3333333333333333, 0.5]
[-0.25, 0.5, 0.75]

CodePudding user response:

If you can interpret the values as being measured on a logarithmic scale, then a reasonable approach is to use the softmax function. SciPy has an implementation in scipy.special.softmax.

For example,

In [39]: softmax([-1, 2, 3])
Out[39]: array([0.01321289, 0.26538793, 0.72139918])

In [40]: softmax([-3, 2, 3])
Out[40]: array([0.00180884, 0.26845495, 0.72973621])

Because the values are on a logarithmic scale, when all the values are positive, you don't get the pro rata results that you mention in the question:

In [43]: softmax([1, 2, 3])
Out[43]: array([0.09003057, 0.24472847, 0.66524096])

In [44]: softmax([2, 2, 3])
Out[44]: array([0.21194156, 0.21194156, 0.57611688])

In [45]: softmax([2, 2.1, 3])
Out[45]: array([0.20732037, 0.22912444, 0.56355519])
  • Related