Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

213
Visualizações
¿Manera numpyica de ordenar un ndarray en el sentido de las agujas del reloj?

Estoy tratando de ordenar un ndarray numpy en el sentido de las agujas del reloj (en orden ascendente). Puede entenderlo como tomar todos los valores de la matriz, ordenarlos y luego colocarlos en una espiral en el sentido de las agujas del reloj en una nueva matriz con la misma forma. Las direcciones de la espiral en el sentido de las agujas del reloj se muestran a continuación:

ingrese la descripción de la imagen aquí

Por ejemplo, supongamos que tengo una matriz de

 import numpy as np a1 = np.array(([2, 4, 6], [1, 5, 3], [7, 9, 8]))

La salida esperada es

 np.array([[1, 2, 3], [8, 9, 4], [7, 6, 5]])

Si tengo una matriz de

 a2 = np.array(([2, 4, 6], [1, 5, 3], [7, 9, 8], [12, 11, 10]))

La salida esperada es

 np.array([[1, 2, 3], [10, 11, 4], [9, 12, 5], [8, 7, 6]])

Lo que he probado hasta ahora

Mi idea es rastrear el índice de fila x y el índice de columna y del iterador en movimiento y el índice actual cur de la lista aplanada ordenada sa . El número de filas por recorrer ( lenr ) y el número de columnas por recorrer ( lenc ) se restan en 1 una vez que el iterador en movimiento pasa lenr filas horizontalmente y lenc columnas verticalmente. Aquí está la función que logré escribir:

 def clockwise_sorted(a, key=None, reverse=False): nr, nc = a.shape res = a.tolist() sa = a.ravel().tolist() if key is None: sa.sort(reverse=reverse) else: sa.sort(key=key, reverse=reverse) res[0] = sa[:nc] cur, lenr, lenc = nc, nr - 1, nc - 1 x, y = 0, nc - 1 while (lenc > 0 and lenr > 0): # go down, then go left for _ in range(lenr): x += 1 res[x][y] = sa[cur] cur += 1 for _ in range(lenc): y -= 1 res[x][y] = sa[cur] cur += 1 lenr -= 1 lenc -= 1 # go up, then go right for _ in range(lenr): x -= 1 res[x][y] = sa[cur] cur += 1 for _ in range(lenc): y += 1 res[x][y] = sa[cur] cur += 1 lenr -= 1 lenc -= 1 return np.array(res)

Para matrices cuadradas, mi código funciona bien:

 print(clockwise_sorted(a1)) #[[1 2 3] # [8 9 4] # [7 6 5]] #%timeit 5.98 µs ± 413 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Pero no funciona para matrices no cuadradas:

 print(clockwise_sorted(a2)) #[[ 1 2 3] # [10 11 4] # [ 9 9 5] # [ 8 7 6]]

Claramente, pierde el 12 en [2,1] .

Tenga en cuenta que no espero que entienda y corrija mi código. No me gusta mucho mi código porque siento que debería haber más formas numpyic de hacer esto. Por lo tanto, quiero ver algunas soluciones numpyic. Sin embargo, sería bueno si alguien puede comentar sobre lo que está mal con mi código.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Es probable que esta no sea la solución más numpy, pero creo que es una solución Pythonic ordenada, ya que es una función generadora que produce coordenadas en espiral en el sentido de las agujas del reloj que luego se usa para indexar la matriz numpy (que debe transponerse dos veces para obtener las coordenadas correctas, pero eso es maní...).

 import numpy as np def spiral_coords(w, h): maxx = w - 1 maxy = h - 1 minx = miny = 0 while (minx, miny) != (maxx, maxy): for x in range(minx, maxx): # right yield (x, miny) yield (maxx, miny) # upper-right corner for y in range(miny + 1, maxy): # down yield (maxx, y) yield (maxx, maxy) # lower-right corner for x in range(maxx - 1, minx, -1): # left yield (x, maxy) yield (minx, maxy) # lower-left corner for y in range(maxy - 1, miny, -1): # up yield (minx, y) minx += 1 miny += 1 maxx -= 1 maxy -= 1 yield (minx, miny) # final point def clockwise_sorted(a): a = aT nr, nc = a.shape sa = a.ravel() sa.sort() res = np.zeros_like(a) for (x, y), v in zip(spiral_coords(nr, nc), sa): res[x, y] = v return res.T a2 = np.array( [ [2, 4, 6], [1, 5, 3], [7, 9, 8], [12, 11, 10], ] ) print(a2) print(clockwise_sorted(a2))

Esto produce

 [[ 2 4 6] [ 1 5 3] [ 7 9 8] [12 11 10]] [[ 1 2 3] [10 11 4] [ 9 12 5] [ 8 7 6]]

Si no necesita necesariamente Numpy, también puede usar el mismo generador para convertir en espiral cualquier cosa, por ejemplo, un mapeo de coordenadas a letras:

 coords = {(x, y): c for (x, y), c in zip(spiral_coords(6, 5), "Hello World! This is a spiral!")} for y in range(5): print("".join(coords.get((x, y), " ") for x in range(6)))

salidas

 Hello is aW sal! o iripsr hT !dl
over 4 years ago · Santiago Trujillo Relatório

0

Puede usar numpy.rot90 con recursividad para girar en el sentido de las agujas del reloj sobre la matriz. Ordene los valores de la matriz después de cambiar a 1d y edite los valores en la matriz por ella

 def rotate(matrix, arr): if not len(matrix): return matrix[0] = arr[:len(matrix[0])] rotate(np.rot90(matrix[1:]), arr[len(matrix[0]):]) a1 = np.array(([2, 4, 6], [1, 5, 3], [7, 9, 8])) sorted_arr = sorted(a1.ravel()) rotate(a1, sorted_arr) print(a1)

Producción

 [[1 2 3] [8 9 4] [7 6 5]]
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda