Как создать массив с заданной нормой и средним значением?

#python #numpy

#python #numpy

Вопрос:

Я хочу создать случайный массив с «нормой» 1 и «средним» 0. Я могу использовать numpy.random.normal() , чтобы получить «среднее значение», которое я хочу, но как я могу создать массив, который numpy.linalg.norm(array) возвращает нужное мне число?

Комментарии:

1. @mkrieger1 Да, что, если результат numpy.linalg.norm равен 0? Тогда это не сработает.

2. Это было бы крайне неудачно.

Ответ №1:

Использование numpy.random.normal с size аргументом даст вам массив со значениями, которые взяты из распределения со средним значением 0. Однако среднее значение массива не будет равно 0 (чем больше массив, тем больше вероятность, что оно будет близко к 0).

Но вы можете легко исправить это, вычитая среднее значение массива.

Получив это, вы можете изменить норму массива на 1, разделив на его норму. Это не изменит среднее значение, потому что оно равно 0.

 def create(n):
     x = numpy.random.normal(size=n)
     x -= x.mean()
     return x / numpy.linalg.norm(x)
 

Пример

 >>> a = create(10)
>>> a
array([-0.48299539,  0.06017975,  0.23788747, -0.31949065,  0.56126426,
       -0.33117035,  0.40908645,  0.01169836, -0.1008337 , -0.0456262 ])
>>> a.mean()
-1.3183898417423733e-17  # not exactly 0 due to floating-point math
>>> numpy.linalg.norm(a)
1.0
 

Обратите внимание, что n=2 существует ровно 2 массива, удовлетворяющих этим условиям: те, которые содержат как положительный, так и отрицательный квадратный корень из 1/2:

 >>> for _ in range(5):
...     print(create(2))
...
[-0.70710678  0.70710678]
[-0.70710678  0.70710678]
[-0.70710678  0.70710678]
[-0.70710678  0.70710678]
[ 0.70710678 -0.70710678]
 

Комментарии:

1. В качестве примечания, для работы этого решения необходимо использовать нормальное распределение, так как использование любого другого распределения, например, равномерного, приведет к случайному вектору, который неравномерно распределен в векторном пространстве с нормой 1 и средним значением 0