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

396
Views
No se puede entender la salida de la partición numpy arg

Estoy tratando de usar arpgpartition de numpy, pero parece que algo va mal y no puedo resolverlo. Esto es lo que está pasando:

Estos son los primeros 5 elementos de las norms de matriz ordenada

 np.sort(norms)[:5] array([ 53.64759445, 54.91434479, 60.11617279, 64.09630585, 64.75318909], dtype=float32)

Pero cuando uso indices_sorted = np.argpartition(norms, 5)[:5]

 norms[indices_sorted] array([ 60.11617279, 64.09630585, 53.64759445, 54.91434479, 64.75318909], dtype=float32)

¿Cuándo creo que debería obtener el mismo resultado que la matriz ordenada?

Funciona bien cuando uso 3 como parámetro indices_sorted = np.argpartition(norms, 3)[:3]

 norms[indices_sorted] array([ 53.64759445, 54.91434479, 60.11617279], dtype=float32)

Esto no tiene mucho sentido para mí, ¿esperando que alguien pueda ofrecer alguna idea?

EDITAR: reformular esta pregunta como si argpartition conserva el orden de los k elementos particionados tiene más sentido.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Necesitamos usar una lista de índices que deben mantenerse ordenados en lugar de alimentar el parámetro k-ésimo como un escalar. Por lo tanto, para mantener la naturaleza ordenada en los primeros 5 elementos, en lugar de np.argpartition(a,5)[:5] , simplemente haga:

 np.argpartition(a,range(5))[:5]

Aquí hay una ejecución de muestra para aclarar las cosas:

 In [84]: a = np.random.rand(10) In [85]: a Out[85]: array([ 0.85017222, 0.19406266, 0.7879974 , 0.40444978, 0.46057793, 0.51428578, 0.03419694, 0.47708 , 0.73924536, 0.14437159]) In [86]: a[np.argpartition(a,5)[:5]] Out[86]: array([ 0.19406266, 0.14437159, 0.03419694, 0.40444978, 0.46057793]) In [87]: a[np.argpartition(a,range(5))[:5]] Out[87]: array([ 0.03419694, 0.14437159, 0.19406266, 0.40444978, 0.46057793])

Tenga en cuenta que argpartition tiene sentido en el aspecto de rendimiento, si buscamos obtener índices ordenados para un pequeño subconjunto de elementos, digamos k número de elementos, que es una pequeña fracción del número total de elementos.

Usemos un conjunto de datos más grande e intentemos obtener índices ordenados para todos los elementos para aclarar el punto mencionado anteriormente:

 In [51]: a = np.random.rand(10000)*100 In [52]: %timeit np.argpartition(a,range(a.size-1))[:5] 10 loops, best of 3: 105 ms per loop In [53]: %timeit a.argsort() 1000 loops, best of 3: 893 µs per loop

Por lo tanto, para ordenar todos los elementos, np.argpartition no es el camino a seguir.

Ahora, digamos que quiero obtener índices ordenados solo para los primeros 5 elementos con ese gran conjunto de datos y también mantener el orden para esos:

 In [68]: a = np.random.rand(10000)*100 In [69]: np.argpartition(a,range(5))[:5] Out[69]: array([1647, 942, 2167, 1371, 2571]) In [70]: a.argsort()[:5] Out[70]: array([1647, 942, 2167, 1371, 2571]) In [71]: %timeit np.argpartition(a,range(5))[:5] 10000 loops, best of 3: 112 µs per loop In [72]: %timeit a.argsort()[:5] 1000 loops, best of 3: 888 µs per loop

¡Muy útil aquí!

over 4 years ago · Santiago Trujillo Report

0

Dada la tarea de ordenar indirectamente un subconjunto (el top k , top significa primero en el orden de clasificación) hay dos soluciones integradas: argsort y argpartition cf. Respuesta de @Divakar.

Sin embargo, si el rendimiento es una consideración, entonces (dependiendo del tamaño de los datos y el subconjunto de interés) puede valer la pena resistir el "atractivo de la línea única", invertir una línea más y aplicar argsort en la salida de argpartition :

 >>> def top_k_sort(a, k): ... return np.argsort(a)[:k] ... >>> def top_k_argp(a, k): ... return np.argpartition(a, range(k))[:k] ... >>> def top_k_hybrid(a, k): ... b = np.argpartition(a, k)[:k] ... return b[np.argsort(a[b])] >>> k = 100 >>> timeit.timeit('f(a,k)', 'a=rng((100000,))', number = 1000, globals={'f': top_k_sort, 'rng': np.random.random, 'k': k}) 8.348663672804832 >>> timeit.timeit('f(a,k)', 'a=rng((100000,))', number = 1000, globals={'f': top_k_argp, 'rng': np.random.random, 'k': k}) 9.869098862167448 >>> timeit.timeit('f(a,k)', 'a=rng((100000,))', number = 1000, globals={'f': top_k_hybrid, 'rng': np.random.random, 'k': k}) 1.2305558240041137

argsort es O(n log n), argpartition con argumento de rango parece ser O(nk) (?), y argpartition + argsort es O(n + k log k)

Por lo tanto, en un régimen interesante n >> k >> 1, se espera que el método híbrido sea el más rápido

ACTUALIZACIÓN: versión ND:

 import numpy as np from timeit import timeit def top_k_sort(A,k,axis=-1): return A.argsort(axis=axis)[(*axis%A.ndim*(slice(None),),slice(k))] def top_k_partition(A,k,axis=-1): return A.argpartition(range(k),axis=axis)[(*axis%A.ndim*(slice(None),),slice(k))] def top_k_hybrid(A,k,axis=-1): B = A.argpartition(k,axis=axis)[(*axis%A.ndim*(slice(None),),slice(k))] return np.take_along_axis(B,np.take_along_axis(A,B,axis).argsort(axis),axis) A = np.random.random((100,10000)) k = 100 from timeit import timeit for f in globals().copy(): if f.startswith("top_"): print(f, timeit(f"{f}(A,k)",globals=globals(),number=10)*100)

Ejemplo de ejecución:

 top_k_sort 63.72379460372031 top_k_partition 99.30561298970133 top_k_hybrid 10.714635509066284
over 4 years ago · Santiago Trujillo Report

0

Describamos el método de partición de una manera simplificada que ayuda mucho a entender argpartition

ingrese la descripción de la imagen aquí

Siguiendo el ejemplo de la imagen si ejecutamos C=numpy.argpartition(A, 3) C será el arreglo resultante de obtener la posición de cada elemento en B con respecto al arreglo A. es decir:

 Idx(z) = index of element z in array A then C would be C = [ Idx(B[0]), Idx(B[1]), Idx(B[2]), Idx(X), Idx(B[4]), ..... Idx(B[N]) ]

Como se mencionó anteriormente, este método es muy útil y es muy útil cuando tiene una matriz enorme y solo está interesado en un grupo seleccionado de elementos ordenados, no en la matriz completa.

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!