Я попытаюсь ответить на этот вопрос в разделах, так как вы используете массивы NumPy, как если бы они были списками, и, следовательно, во-первых, теряете большую часть цели библиотеки. Хотя синтаксис намного более компактен, он имеет значительное увеличение скорости.
Создание группы населения
Этот достаточно прост. Мы можем сделать прямую замену для генерации pop
, используя numpy.random.randint
. Нам нужно указать значения для population_size
и chromosome length
и использовать их для определения размера вывода.
population_size = 6
chromosome_length = 10
pop = np.random.randint(0, 2, (population_size, chromosome_length))
ПРИМЕЧАНИЕ : Это не даст те же самые значения, которые вы включили в свой фактический вопрос, потому что мы не установили начальное число для генератора случайных чисел. Однако код прямо эквивалентен вашему for
l oop, но более производительный.
Генерация expected
Я не могу сделать точную замену для этого раздела, потому что он слишком много, чтобы заменить ваши циклы, причем некоторые переменные также не определены. Итак, я просто предполагаю, что получу тот же 2D-массив, как вы показали:
expected = np.array([[1.99214608],
[1.45140389],
[0.07068525],
[0.69507167],
[1.08384057],
[0.70685254]])
Объединение данных
Это немного сложнее. Мы можем использовать numpy.digitize
, чтобы связать данные между вашими интервалами (0, 0,9 и 1,5). Однако этот метод не будет работать с двумерными массивами, поэтому я собираюсь сначала использовать numpy.ravel()
для выравнивания массива.
Это вернет список идентификаторов бинов, которые Каждое значение expected
принадлежит. Однако идентификаторы бинов начинаются с 1, и мы хотим использовать эти значения, так как указывает на массива в дальнейшем, поэтому я также собираюсь одновременно вычесть 1 из результата.
bins = np.array([0, 0.9, 1.5])
dig = np.digitize(expected.ravel(), bins) - 1
Последние шаги
Я собираюсь создать массив значений, которые соответствуют категориям бинов. Затем мы можем использовать numpy.take
для замены значений dig
соответствующими значениями замены.
replacements = np.array([0, 1, 2])
actual = np.take(replacements, dig)
И наконец :), мы можем использовать numpy.repeat
с использованием actual
для получения строк из pop
в правильных пропорциях для построения выходных данных.
Окончательный код
import numpy as np
population_size = 6
chromosome_length = 10
pop = np.random.randint(0, 2, (population_size, chromosome_length))
# But I'm going to deliberately overwrite the above to solve your particular case
pop = np.array([[0., 1., 0., 1., 1., 1., 0., 0., 1., 1.],
[0., 0., 1., 0., 1., 0., 1., 1., 0., 0.],
[0., 0., 1., 0., 0., 1., 1., 0., 0., 1.],
[0., 0., 0., 0., 1., 0., 1., 1., 1., 0.],
[0., 0., 0., 0., 1., 0., 1., 1., 0., 1.],
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]])
# Hard-coded :/
expected = np.array([[1.99214608],
[1.45140389],
[0.07068525],
[0.69507167],
[1.08384057],
[0.70685254]])
bins = np.array([0, 0.9, 1.5])
dig = np.digitize(expected.ravel(), bins) - 1
replacements = np.array([0, 1, 2])
actual = np.take(replacements, dig)
out = np.repeat(pop, actual, axis=0)
print(out)
Дает:
[[0. 1. 0. 1. 1. 1. 0. 0. 1. 1.]
[0. 1. 0. 1. 1. 1. 0. 0. 1. 1.]
[0. 0. 1. 0. 1. 0. 1. 1. 0. 0.]
[0. 0. 0. 0. 1. 0. 1. 1. 0. 1.]]