Repetir cada valores de una matriz de tiempos diferentes.

Supongamos que a = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6] y s = [3, 3, 9, 3, 6, 3] . Estoy buscando la mejor manera de repetir a[i] exactamente s[i] veces y luego tener una matriz plana en la forma de b = [0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, ... ] .

Quiero hacer esto lo más rápido posible ya que tengo que hacerlo muchas veces. Estoy usando Python y numpy y las matrices se definen como numpy.ndarray. Busqué y encontré repeat , column_stack y column_stack que se pueden usar bien para repetir cada elemento n veces, pero quería repetir cada una de ellas en diferentes ocasiones.

Una forma de hacer esto es:

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

Me pregunto si hay una mejor manera de hacerlo.

Eso es exactamente lo que hace 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]) 

En Python puro puedes hacer algo como:

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

Pero, por supuesto, va a ser mucho más lento que su equivalente 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 

Aquí hay una sola línea que usa solo listas de comprensión (anidadas):

 [item for z in [[x]*y for (x,y) in zip(a, s)] for item in z]