In Numpy, we want to generate an n-dimensional random vector under the constraint that the sum of the number of elements is N.

Asked 2 years ago, Updated 2 years ago, 55 views

I would like to create an n-dimensional random vector v with Numpy.
I want the sum of the elements of the vector to be N.

For example,
If n=4 and N=1, v=np.array([0.1, 0.3, 0.2, 0.4])
Or
If n=6 and N=3, v=np.array([0.3, 0.1, 1.2, 0.6, 0.5, 0.3])
It's like this.

How can I do this with Numpy?

python numpy

2022-09-30 16:17

3 Answers

If you don't care about some errors, you can generate n random numbers and then normalize them.

>>import numpy as np
>>>n=7
>>>N=3
>> random_number=np.random.rand(n)
>>print(random_number)
[ 0.61444461  0.44538832  0.80188737  0.57265561  0.05225624  0.07613083
  0.55669533]
>>print(np.sum(random_number))
3.11945832298
>>answer=N* random_number/np.sum (random_number)
>> print (answer)
[ 0.59091472  0.42833237  0.77117943  0.55072601  0.05025511  0.07321543
  0.53537692]
>>print(np.sum(answer))
3.0


2022-09-30 16:17

SO English version had the same question.

import numpy as np

n = 7
N = 3

answer=np.random.dirichlet(np.ones(n))*N

print("n=", answer.size)
print("N=", answer.sum())
print(answer)

Results

n=7
N = 3.0
[ 0.23253049  1.45542211  0.36459806  0.39199048  0.31374561  0.20020738
  0.04150587]

If np.ones(n) is multiplied by the coefficient, the distribution of random numbers can be changed.See the English version for more information.


2022-09-30 16:17

There seems to be another way to do this, but if you take the sum you want as the range of random numbers and take n-2 random numbers out of the range, sort them from small to large numbers in addition to the upper and lower limits, you'll get the value you want.

import numpy as np, numpy.random
// Let N=3 sum be 3, i.e., the range of random numbers below be 3. 
 The lower limit is 0.0 and the upper limit is 3.0, and np.random.uniform should not output the upper limit.
// n=6 The number of elements is set to 6.
values = numpy.array([0.0,N]);
x = np.random.uniform (0.0, N, size = n-2);
values = numpy.append(x, values);
values.sort();
print(values) 
// [0.0.83087151 1.27426042 1.47701249 2.835177233.] 0, 3. should be 0.0, 3.0.By repl.it.
results = numpy.array([]);
for i in range (1, 6):
     results = numpy.append(results, values[i]-values[i-1]);
print(np.sum(results));
// 3.0


2022-09-30 16:17

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.