python - write - Entrelazando dos matrices numpy
python numpy matrix add element (9)
Aquí hay un trazador de líneas:
c = numpy.vstack((a,b)).reshape((-1,),order=''F'')
Supongamos que se dan las siguientes matrices:
a = array([1,3,5])
b = array([2,4,6])
¿Cómo se podría entrelazar de manera eficiente para que uno obtenga una tercera matriz como esta?
c = array([1,2,3,4,5,6])
Se puede suponer que la length(a)==length(b)
.
Aquí hay una respuesta más simple que algunas de las anteriores
import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
inter = np.ravel(np.column_stack((a,b)))
Después de este inter
contiene:
array([1, 2, 3, 4, 5, 6])
Esta respuesta también parece ser marginalmente más rápida:
In [4]: %timeit np.ravel(np.column_stack((a,b)))
100000 loops, best of 3: 6.31 µs per loop
In [8]: %timeit np.ravel(np.dstack((a,b)))
100000 loops, best of 3: 7.14 µs per loop
In [11]: %timeit np.vstack((a,b)).ravel([-1])
100000 loops, best of 3: 7.08 µs per loop
Esto intercalará / entrelazará las dos matrices y creo que es bastante legible:
a = np.array([1,3,5]) #=> array([1, 3, 5])
b = np.array([2,4,6]) #=> array([2, 4, 6])
c = np.hstack( zip(a,b) ) #=> array([1, 2, 3, 4, 5, 6])
Me gusta la respuesta de Josh. Solo quería agregar una solución más mundana, habitual y un poco más detallada. No sé cuál es más eficiente. Espero que tengan un rendimiento similar.
import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
c = np.empty((a.size + b.size,), dtype=a.dtype)
c[0::2] = a
c[1::2] = b
Mejorando la respuesta de @xioxox:
import numpy as np a = np.array([1,3,5]) b = np.array([2,4,6]) inter = np.ravel((a,b), order=''F'')
Pensé que podría valer la pena comprobar cómo funcionaban las soluciones en términos de rendimiento. Y este es el resultado:
Esto muestra claramente que la respuesta más votada y aceptada (respuesta de Pauls) también es la opción más rápida.
El código fue tomado de las otras respuestas y de otras preguntas y respuestas :
# Setup
import numpy as np
def Paul(a, b):
c = np.empty((a.size + b.size,), dtype=a.dtype)
c[0::2] = a
c[1::2] = b
return c
def JoshAdel(a, b):
return np.vstack((a,b)).reshape((-1,),order=''F'')
def xioxox(a, b):
return np.ravel(np.column_stack((a,b)))
def Benjamin(a, b):
return np.vstack((a,b)).ravel([-1])
def andersonvom(a, b):
return np.hstack( zip(a,b) )
def bhanukiran(a, b):
return np.dstack((a,b)).flatten()
def Tai(a, b):
return np.insert(b, obj=range(a.shape[0]), values=a)
def Will(a, b):
return np.ravel((a,b), order=''F'')
# Timing setup
timings = {Paul: [], JoshAdel: [], xioxox: [], Benjamin: [], andersonvom: [], bhanukiran: [], Tai: [], Will: []}
sizes = [2**i for i in range(1, 20, 2)]
# Timing
for size in sizes:
func_input1 = np.random.random(size=size)
func_input2 = np.random.random(size=size)
for func in timings:
res = %timeit -o func(func_input1, func_input2)
timings[func].append(res)
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(1)
ax = plt.subplot(111)
for func in timings:
ax.plot(sizes,
[time.best for time in timings[func]],
label=func.__name__) # you could also use "func.__name__" here instead
ax.set_xscale(''log'')
ax.set_yscale(''log'')
ax.set_xlabel(''size'')
ax.set_ylabel(''time [seconds]'')
ax.grid(which=''both'')
ax.legend()
plt.tight_layout()
En caso de que tengas numba disponible, también podrías usar eso para crear una función:
import numba as nb
@nb.njit
def numba_interweave(arr1, arr2):
res = np.empty(arr1.size + arr2.size, dtype=arr1.dtype)
for idx, (item1, item2) in enumerate(zip(arr1, arr2)):
res[idx*2] = item1
res[idx*2+1] = item2
return res
Podría ser un poco más rápido que las otras alternativas:
Tal vez esto sea más legible que la solución de @ JoshAdel:
c = numpy.vstack((a,b)).ravel([-1])
También se puede probar np.insert
. (Solución migrada desde las matrices numeradas Interleave )
import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
np.insert(b, obj=range(a.shape[0]), values=a)
Por favor, consulte la documentation
y el tutorial
para obtener más información.
vstack
seguro es una opción, pero una solución más directa para su caso podría ser el hstack
>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> hstack((a,b)) #remember it is a tuple of arrays that this function swallows in.
>>> array([1, 3, 5, 2, 4, 6])
>>> sort(hstack((a,b)))
>>> array([1, 2, 3, 4, 5, 6])
y más importante, esto funciona para formas arbitrarias de a
y b
También es posible que desee probar dstack
>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> dstack((a,b)).flatten()
>>> array([1, 2, 3, 4, 5, 6])
tienes opciones ahora!