I need to generate two lists (let's call them X and Y) that sum to a specific number.
The function I need to create will take as inputs length of X and Y and the sum.
Then it creates random positive numbers for X and negative numbers for Y and normalizes them to sum to the number I want.
I've tried doing it like this:
def extractAmount(ina, outa, balance):
# ina: length of X, outa: length of Y, balance: the number I want
valin = random.random((1, ina)) # X
valout = -random.random((1, outa)) # Y
val = np.concatenate([valin[0], valout[0]])
valf = (np.round(val / abs(np.sum(val)) * abs(balance))).tolist()
return valf
The code works both for positive and negative numbers as balance
, how could I improve it to work also if balance == 0
?
If I do extractAmount(2, 3, 100)
, the output is [49.0, 350.0, -44.0, -68.0, -186.0]
, my problem is that if I do extractAmount(2, 3, 0)
, it returns [0.0, 0.0, 0.0, 0.0, 0.0]
while I need it to be random values, not all zeros.
CodePudding user response:
I think you need one more constraint for the problem to be well-defined. For example, you could require that the x values have a certain mean, say 200. Then you can first scale the random x values to meet that requirement, and then scale the random y values to meet the balance requirement in conjunction with x:
import numpy as np
def extract_amount(length_x, length_y, mean_x, balance):
x = np.random.random(length_x)
x *= mean_x / np.mean(x)
y = np.random.random(length_y)
mean_y = (np.sum(x) - balance) / length_y
y *= - mean_y / np.mean(y)
return x, y
# Example 1
extract_amount(2, 3, 200, 100)
(array([224.47381339, 175.52618661]),
array([-101.83346151, -181.49633185, -16.67020665]))
# Example 2
extract_amount(2, 3, 200, 0)
(array([268.78299914, 131.21700086]),
array([ -80.71742313, -125.50531378, -193.77726309]))