Как скопировать элементы массива на основе элементов другого массива? - PullRequest
0 голосов
/ 22 апреля 2020
pop=np.zeros((population_size,chromosome_length))
for i in range(population_size):
    for j in range(i,chromosome_length):
        pop[i,j] = random.randint(0, 1)        
pop

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.]])

У меня есть другой массив expected, сгенерированный из непоказанного кода, с примером ниже:

array([[1.99214608],
       [1.45140389],
       [0.07068525],
       [0.69507167],
       [1.08384057],
       [0.70685254]])

Затем я хочу скопировать значения expected на основе пользовательских интервалов :

actual=np.zeros((population_size,1))
for i in range(len(expected)):
    if expected[i]>=1.5:
        actual[i]=2
    elif 1.5>expected[i]>=0.9:
        actual[i]=1
    else:
        actual[i]=0
actual=actual.astype(int)   
total_count=int(np.sum(actual))
print(total_count)

[[2]
 [1]
 [0]
 [0]
 [1]
 [0]]
 4

, и я хочу, чтобы окончательный вывод был:

array([[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.]])

на основе значений в total_count. Первый ряд pop был скопирован дважды, второй ряд один раз и пятый ряд один раз. Короче говоря, я хочу повторять / копировать / дублировать элементы массива на основе целочисленного элемента другого массива.

1 Ответ

1 голос
/ 22 апреля 2020

Я попытаюсь ответить на этот вопрос в разделах, так как вы используете массивы 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.]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...