users python3 org mac python multidimensional-array numpy swap

python3 - Intercambia rebanadas de matrices Numpy



python3 numpy (4)

Encuentro esto el más simple:

a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:, 0, 0].copy() #swap

Comparación de tiempo:

%timeit a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:, 0, 0].copy() #swap The slowest run took 10.79 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 1.75 µs per loop %timeit t = np.copy(a[:,0,0]); a[:,0,0] = b[:,0,0]; b[:,0,0] = t The slowest run took 10.88 times longer than the fastest. This could mean that an intermediate result is being cached 100000 loops, best of 3: 2.68 µs per loop

Me encanta la forma en que python está manejando los cambios de variables: a, b, = b, a

y me gustaría usar esta funcionalidad para intercambiar valores entre las matrices, no solo de a una, sino de varias (sin usar una variable de temperatura). Esto no es lo que esperaba (esperaba que ambas entradas a lo largo de la tercera dimensión cambiarían por ambas):

import numpy as np a = np.random.randint(0, 10, (2, 3,3)) b = np.random.randint(0, 10, (2, 5,5)) # display before a[:,0, 0] b[:,0,0] a[:,0,0], b[:, 0, 0] = b[:, 0, 0], a[:,0,0] #swap # display after a[:,0, 0] b[:,0,0]

¿Alguien tiene alguna idea? Por supuesto, siempre puedo introducir una variable adicional, pero me preguntaba si había una forma más elegante de hacerlo.


Esto funcionará

a[:,0,0], b[:, 0, 0] = b[:, 0, 0].copy(), a[:, 0, 0].copy()


Python interpreta correctamente el código como si usara variables adicionales, por lo que el código de intercambio es equivalente a:

t1 = b[:,0,0] t2 = a[:,0,0] a[:,0,0] = t1 b[:,0,0] = t2

Sin embargo, ¡incluso este código no intercambia valores correctamente! Esto se debe a que las slices Numpy no copian los datos con entusiasmo, sino que crean vistas en los datos existentes. Las copias se realizan solo en el punto en el que se asignan las divisiones, pero cuando se intercambia, la copia sin un buffer intermedio destruye sus datos. Es por eso que no solo necesita una variable adicional, sino también un búfer numpy adicional, cuya sintaxis general de Python no puede saber nada. Por ejemplo, esto funciona como se esperaba:

t = np.copy(a[:,0,0]) a[:,0,0] = b[:,0,0] b[:,0,0] = t


La respuesta de user4815162342 es de hecho la respuesta "correcta". Pero si realmente buscas un proyecto de una sola línea, considera esto:

a[arange(2),0,0], b[arange(2), 0, 0] = b[arange(2), 0, 0], a[arange(2),0,0] #swap

Sin embargo, esto es significativamente menos eficiente:

In [12]: %timeit a[arange(2),0,0], b[arange(2), 0, 0] = b[arange(2), 0, 0], a[arange(2),0,0] 10000 loops, best of 3: 32.2 µs per loop In [13]: %timeit t = np.copy(a[:,0,0]); a[:,0,0] = b[:,0,0]; b[:,0,0] = t The slowest run took 4.14 times longer than the fastest. This could mean that an intermediate result is being cached 100000 loops, best of 3: 13.3 µs per loop

(pero observe la nota sobre "la ejecución más lenta" ... si intenta llamar a% timeit con "-n 1 -r 1", verá resultados más comparables, aunque con mi solución siendo ~ 50% más lenta) demostrando eso sí, el almacenamiento en caché está afectando los tiempos)