Создать массив, содержащий список списков из n повторяющихся элементов в Python - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь найти более быстрый способ создания такого списка:

import numpy as np
values = [0,1,2]
repeat = [3,4,2]
list = np.empty(0, dtype=int)
for i in range(len(values)):
    list = np.append(list, np.full(repeat[i], values[i]))
print list

возвращает

[0 0 0 1 1 1 1 2 2]

Есть идеи? Спасибо

Ответы [ 4 ]

0 голосов
/ 12 сентября 2018
In [8]: [i for i, j in zip(values, repeat) for _ in range(j)]
Out[8]: [0, 0, 0, 1, 1, 1, 1, 2, 2]

Здесь мы архивируем значения и повторяем их вместе с zip, чтобы между ними было однозначное соответствие (например, [(0, 3), (1, 4), (2, 2)]). Теперь, в понимании списка, я вставляю значения i или и зацикливаю их в диапазоне j, чтобы повторить это j-й раз.

0 голосов
/ 12 сентября 2018

Вы можете попробовать это. Умножьте списки значений по длинам для каждой пары значений и длин.
Вы получите список списков

L = [[i]*j for i, j in zip(values, repeat)] 
print(L)

возвращает

[[0, 0, 0], [1, 1, 1, 1], [2, 2]]

Чем составить плоский список

flat_L = [item for sublist in L for item in sublist] 
print(flat_L)
[0, 0, 0, 1, 1, 1, 1, 2, 2]
0 голосов
/ 12 сентября 2018

Я бы сделал так:

a=[1,2,3]
b=[2,4,3]
x=[[y]*cnt_b for cnt_b,y in zip(b,a)]

Выход:

[[1,1], [2,2,2,2], [3,3,3]]

0 голосов
/ 12 сентября 2018

Вы можете сэкономить много времени, используя собственные списки Python вместо массивов. Когда я запустил ваш код с помощью модуля timeit, это заняло 16,87 секунды. Следующий код занял 0,87.

list = []
for val, rep in zip(values, repeat):
    list.extend([val]*rep)

Если затем преобразовать список в массив с использованием list = np.array(list), это время возрастет до 2,09 секунды.

Конечно, поскольку numpy оптимизирован для больших объемов данных , это может не выполняться для очень длинных списков значений с большим количеством повторов. В этом случае одной из альтернатив будет выделение памяти одновременно, а не постоянное удлинение массива (что, как я полагаю, скрытно заставляет сделать копию , что медленно). Пример ниже завершается за 4,44 секунды.

list = np.empty(sum(repeat), dtype=int) #allocate the full length
i=0 #start the index at 0
for val, rep in zip (values, repeat):
    list[i:i+rep] = [val]*rep #replace the slice
    i+=rep #update the index
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...