#python #numpy #random
Вопрос:
Мне нужно сгенерировать два списка (назовем их X и Y), сумма которых равна определенному числу.
Функция, которую мне нужно создать, будет принимать в качестве входных данных длину X и Y и сумму.
Затем он создает случайные положительные числа для X и отрицательные числа для Y и нормализует их, чтобы сложить в число, которое я хочу.
Я пробовал делать это вот так:
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
Код работает как для положительных , так и для отрицательных чисел, поскольку balance
, как я мог бы улучшить его, чтобы он также работал, если balance == 0
бы ?
Если я это сделаю extractAmount(2, 3, 100)
, то на выходе получится [49.0, 350.0, -44.0, -68.0, -186.0]
, что моя проблема в том , что если я это сделаю extractAmount(2, 3, 0)
, он вернется [0.0, 0.0, 0.0, 0.0, 0.0]
, в то время как мне нужно, чтобы это были случайные значения, а не все нули.
Комментарии:
1. Меня смущает, чего ты на самом деле хочешь. Вы сказали, что функция принимает длины каждого списка, но, исходя из вашего кода, ina-это максимальное значение положительных чисел, а outa-максимальное значение отрицательных чисел.
2. Вы должны предоставить примеры ввода/вывода
3. ina и outa-это длина, которую я хочу для X и Y (в коде valin и valout). Используя random.random((1,3)) (как в ina=3), я получаю 3 случайных числа в массиве, я ошибаюсь?
4. @DuccioBorchi вы используете Python 2 или 3? Модуль random для меня так не работает. передача кортежа в random.random приводит к исключению аргумента
5. Python 3, и это работает для меня
Ответ №1:
Я думаю, что вам нужно еще одно ограничение, чтобы проблема была четко определена. Например, вы можете потребовать, чтобы значения x имели определенное среднее значение, скажем, 200. Затем вы можете сначала масштабировать случайные значения x, чтобы удовлетворить этому требованию, а затем масштабировать случайные значения y, чтобы удовлетворить требованию баланса в сочетании с 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]))
Комментарии:
1. Это может быть решением, единственная проблема в том, что у меня нет среднего значения для x или y, я думаю, что, возможно, я мог бы сгенерировать число, а затем сгенерировать остальные, начиная с первого
2. Но вам все равно нужно будет ввести ограничение на то, как вы создадите это первое число. Если у вас нет среднего значения, может быть, вы могли бы обосновать какое-то максимальное значение для элементов x и использовать
np.random.randint
для генерации x без масштабирования?3. Да, мне это понравилось, и это работает, я использовал a
(random.random()*b_mean)/ina
, где ina-длина x, а b_mean-среднее значение всего баланса (раньше они хранились в словаре). Поэтому я думаю, что это хорошее решение, если вы знаете возможное среднее значение одного из векторов