Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

174
Views
Usando numpy para construir una matriz con filas extraídas de otra matriz 2D como bloques 2x2

Supongamos que tengo la siguiente matriz 2D:

 x = np.array([[10,20,30,40], [50,60,70,80],[90,100,110,120]]) print(x) array([[ 10, 20, 30, 40], [ 50, 60, 70, 80], [ 90, 100, 110, 120]])

Me gustaría construir una nueva matriz, y , donde cada fila tenga los valores de un bloque de 2x2 desde x en el sentido de las agujas del reloj:

 print(y) array([[ 10, 20, 60, 50], [ 20, 30, 70, 60], [ 30, 40, 80, 70], [ 50, 60, 100, 90], [ 60, 70, 110, 100], [ 70, 80, 120, 110]])

Podría lograr eso usando Python para bucles de la siguiente manera:

 n_rows, n_cols = x.shape y = [] for i in range(n_rows-1): for j in range(n_cols-1): row = [x[i,j],x[i,j+1],x[i+1, j+1],x[i+1,j]] y.append(row) y = np.array(y)

Me pregunto si hay una forma más rápida que aproveche las funciones de Numpy y evite usar bucles de Python.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Primero, cree una vista de sliding_window_view en x con los cuadros de 2x2 que desea ver:

 b = np.lib.stride_tricks.sliding_window_view(x, (2, 2))

Cada una de las matrices de 2x2 más internas contiene una versión desenredada de lo que desea, pero con la segunda parte de la matriz invertida. Hasta ahora no hemos copiado ningún dato. Ahora haz una copia deshilachando la última dimensión. La remodelación siempre hará una copia aquí porque b es altamente no contigua:

 c = b.reshape(*b.shape[:2], 4)

Cambia las dos últimas columnas:

 c[..., 2:] = c[..., -1:1:-1]

Ahora enreda las dimensiones principales:

 y = c.reshape(-1, c.shape[-1])

Si tiene una versión de numpy anterior a la 1.20, puede reemplazar la definición de b con

 b = np.lib.stride_tricks.as_strided(x, shape=(x.shape[0] - 1, x.shape[1] - 1, 2, 2), strides=x.strides * 2)
over 4 years ago · Santiago Trujillo Report

0

Puede almacenar en caché su código ya que el ciclo itera principalmente la misma matriz una y otra vez (si desea mantener su mismo código con el ciclo). He hecho una comparación de velocidad para su código antes y después del almacenamiento en caché.

 # Before caching def loop_before_cache(): n_rows, n_cols = x.shape y = [] for i in range(n_rows-1): for j in range(n_cols-1): row = [x[i,j],x[i,j+1],x[i+1, j+1],x[i+1,j]] y.append(row) return np.array(y) %timeit loop_before_cache() 11.6 µs ± 318 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Y ahora con el almacenamiento en caché

 # After caching from functools import lru_cache @lru_cache() def loop_after_cache(): n_rows, n_cols = x.shape y = [] for i in range(n_rows-1): for j in range(n_cols-1): row = [x[i,j],x[i,j+1],x[i+1, j+1],x[i+1,j]] y.append(row) return np.array(y) %timeit loop_after_cache() 83.6 ns ± 2.42 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

Extra

He agregado datos simulados con una matriz (1000,5000) usando el range para mostrar la eficiencia del almacenamiento en caché.

 x = np.array([i for i in range(1,5000001)]) x = np.reshape(x, (1000,5000)) # Before caching def loop_before_cache(): n_rows, n_cols = x.shape y = [] for i in range(n_rows-1): for j in range(n_cols-1): row = [x[i,j],x[i,j+1],x[i+1, j+1],x[i+1,j]] y.append(row) return np.array(y) %timeit loop_before_cache() 8.58 s ± 113 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
 # After caching @lru_cache(maxsize = 256) def loop_after_cache(): n_rows, n_cols = x.shape y = [] for i in range(n_rows-1): for j in range(n_cols-1): row = [x[i,j],x[i,j+1],x[i+1, j+1],x[i+1,j]] y.append(row) return np.array(y) %timeit loop_after_cache() 82.2 ns ± 5.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!