2014-09-25 4 views
1

Предположим, что a = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] и s = [3, 3, 9, 3, 6, 3]. Я ищу лучший способ повторить a[i] ровно s[i] раз, а затем иметь сплющенный массив в виде b = [0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, ... ].Повторите все значения массива в разное время

Я хочу сделать это как можно быстрее, так как я должен это делать много раз. Я использую Python и numpy, а массивы определяются как numpy.ndarray. Я искал вокруг и узнал о repeat, tile и column_stack, которые могут быть использованы красиво, чтобы повторять каждый элемент n раз, но я хотел повторять каждый из них разное время.

Один из способов сделать это:

a = hsplit(a, 6) 
for i in range(len(a)): 
    a[i] = repeat(a[i], s[i]) 
a = a.flatten() 

мне интересно, если есть лучший способ сделать это.

+0

является вашей функцией повтора 'np.repeat?' – Kasramvd

+0

@ Kasra Да, это так. Я не знал, что он также принимает список для повтора. – Amir

+0

, поэтому вы должны написать 'np.repeat' !!! будьте осторожны с вашими валидационными вопросами и ясными !!! – Kasramvd

ответ

8

Это именно то, что numpy.repeat делает:

>>> a = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6]) 
>>> s = np.array([3, 3, 9, 3, 6, 3]) 
>>> np.repeat(a, s) 
array([ 0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, 0.3, 
     0.3, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, 0.5, 0.5, 0.5, 0.5, 
     0.5, 0.5, 0.6, 0.6, 0.6]) 

В чистом Python вы можете сделать что-то вроде:

>>> from itertools import repeat, chain, imap 
>>> list(chain.from_iterable(imap(repeat, a, s))) 
[0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.6, 0.6, 0.6] 

Но, конечно, это будет путь медленнее, чем его NumPy эквивалент:

>>> s = [3, 3, 9, 3, 6, 3]*1000 
>>> a = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]*1000 
>>> %timeit list(chain.from_iterable(imap(repeat, a, s))) 
1000 loops, best of 3: 1.21 ms per loop 
>>> %timeit np.repeat(a_a, s_a) #a_a and s_a are NumPy arrays of same size as a and b 
10000 loops, best of 3: 202 µs per loop 
+3

на самом деле самый эффективный –

+0

Не могу поверить, что я не тестировал это. Благодарю. – Amir

-1

Это однострочный адрес, содержащий только встроенные вложения:

[item for z in [[x]*y for (x,y) in zip(a, s)] for item in z] 
Смежные вопросы