Estoy usando una forma 2D matriz para almacenar pares de longitudes+latitudes. En un momento, tengo que combinar dos de estas matrices 2D y, a continuación, eliminar cualquier entrada duplicada. He estado buscando una función similar a la de numpy.único, pero no he tenido suerte. Cualquier aplicación que he sido
pensando en looks muy «unoptimizied». Por ejemplo, estoy tratando de convertir la matriz en una lista de tuplas, eliminación de duplicados con set y, a continuación, convertir a una matriz de nuevo:

coordskeys = np.array(list(set([tuple(x) for x in coordskeys])))

Hay soluciones existentes, por lo que no reinventar la rueda?

Para que quede claro, yo estoy buscando:

>>> a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
>>> unique_rows(a)
array([[1, 1], [2, 3],[5, 4]])

BTW, yo quería usar sólo una lista de tuplas, pero las listas son tan grandes que se consume mis 4Gb de RAM + 4Gb de swap (numpy matrices de memoria más eficiente).

InformationsquelleAutor Sergi | 2011-12-19

6 Comentarios

  1. 17

    Aquí es una idea, que va a tomar un poco de trabajo, pero podría ser bastante rápida. Te voy a dar la 1d caso y vamos a averiguar cómo extender a 2d. La siguiente función se encuentra los elementos singulares de una 1d array:

    import numpy as np
    def unique(a):
        a = np.sort(a)
        b = np.diff(a)
        b = np.r_[1, b]
        return a[b != 0]

    Ahora para extender a 2d necesita cambiar dos cosas. Usted tendrá que averiguar cómo hacer el tipo de ti, lo importante sobre el tipo de ser que dos idénticos entradas de terminar uno al lado del otro. En segundo lugar, usted necesita para hacer algo como (b != 0).all(axis) porque quieres comparar toda la fila/columna. Déjeme saber si eso es suficiente para empezar.

    actualizado: Con ayuda de doug, yo creo que esto debería funcionar para el 2d caso.

    import numpy as np
    def unique(a):
        order = np.lexsort(a.T)
        a = a[order]
        diff = np.diff(a, axis=0)
        ui = np.ones(len(a), 'bool')
        ui[1:] = (diff != 0).any(axis=1) 
        return a[ui]
    • +1 acaba de publicar mi respuesta, luego de leer el suyo, se ve como el mío es un fiel 2D implementación de la suya: la misma secuencia de funciones idénticas (incluso tenía una fila de la concatenación de paso al principio, pero me lo quitaron y rodajas de primera fila fuera de la matriz original en su lugar.
    • Tenga en cuenta que esta parece que no funciona con Python3
    • esta respuesta en su mayoría utiliza el numpy para python2/3 no’ importa. Si no funciona para usted, probablemente hay algo más.
    • Trabajó para mí en Python3. Tenga en cuenta que esto no conservar el orden.
    • Tenga en cuenta que el lexsort solución es limitada en cuántas columnas se apoya
  2. 31

    Esto debe hacer el truco:

    def unique_rows(a):
        a = np.ascontiguousarray(a)
        unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
        return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))

    Ejemplo:

    >>> a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
    >>> unique_rows(a)
    array([[1, 1],
           [2, 3],
           [5, 4]])
    • Agradable y conciso!
    • Nota: esto no funcionará con una matriz traspuesta.
    • editado de tal manera que funcione con transposición de matrices.
  3. 5

    Mi método es mediante el giro de una matriz 2d en 1d compleja matriz, donde la parte real es la 1ª columna, la parte imaginaria es la 2ª columna. A continuación, el uso de la np.único. A pesar de que esto sólo funciona con 2 columnas.

    import numpy as np 
    def unique2d(a):
        x, y = a.T
        b = x + y*1.0j 
        idx = np.unique(b,return_index=True)[1]
        return a[idx] 

    Ejemplo –

    a = np.array([[1, 1], [2, 3], [1, 1], [5, 4], [2, 3]])
    unique2d(a)
    array([[1, 1],
           [2, 3],
           [5, 4]])
  4. 3
    >>> import numpy as NP
    >>> # create a 2D NumPy array with some duplicate rows
    >>> A
    array([[1, 1, 1, 5, 7],
    [5, 4, 5, 4, 7],
    [7, 9, 4, 7, 8],
    [5, 4, 5, 4, 7],
    [1, 1, 1, 5, 7],
    [5, 4, 5, 4, 7],
    [7, 9, 4, 7, 8],
    [5, 4, 5, 4, 7],
    [7, 9, 4, 7, 8]])
    >>> # first, sort the 2D NumPy array row-wise so dups will be contiguous
    >>> # and rows are preserved
    >>> a, b, c, d, e = A.T    # create the keys for to pass to lexsort
    >>> ndx = NP.lexsort((a, b, c, d, e))
    >>> ndx
    array([1, 3, 5, 7, 0, 4, 2, 6, 8])
    >>> A = A[ndx,]
    >>> # now diff by row
    >>> A1 = NP.diff(A, axis=0)
    >>> A1
    array([[0, 0, 0, 0, 0],
    [4, 3, 3, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 0, 1, 0, 0],
    [2, 5, 0, 2, 1],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0]])
    >>> # the index array holding the location of each duplicate row
    >>> ndx = NP.any(A1, axis=1)  
    >>> ndx
    array([False,  True, False,  True,  True,  True, False, False], dtype=bool)  
    >>> # retrieve the duplicate rows:
    >>> A[1:,:][ndx,]
    array([[7, 9, 4, 7, 8],
    [1, 1, 1, 5, 7],
    [5, 4, 5, 4, 7],
    [7, 9, 4, 7, 8]])
    • Doug, creo que estamos cerca, pero va a ejecutar en problemas porque NP.sort(A, eje=0) tipo de cada columna de forma independiente. Intente ejecutar su método en los dos siguientes matrices: [[0, 0], [1, 1], [2,2]] y [[0, 1], [1, 0], [2,2]]. He añadido una función de ordenación mi mi respuesta que mantiene las filas intacta, mientras que la ordenación.
    • gracias por la captura de ese–acaba de editar para corregir.
    • Yo no sabía acerca de lexsort, voy a incluir en mi respuesta, si eso está bien
    • absolutamente-ustedes fueron los primeros en haber resuelto el corazón del problema, de todos modos, es por eso que hasta votado su respuesta, y deja un comentario para que la gente sepa que mi respuesta es solo una versión modificada de la suya publicado varias horas más tarde.
  5. 3

    La numpy_indexed paquete (descargo de responsabilidad: yo soy su autor) se ajusta la solución publicado por user545424 en un agradable y prueba de la interfaz, además de muchas funciones relacionadas:

    import numpy_indexed as npi
    npi.unique(coordskeys)
  6. 1

    ya que se refieren a numpy.único, usted dont care para mantener el orden original, ¿correcto? la conversión en conjunto, lo que elimina duplicados y, a continuación, volver a la lista se utiliza a menudo modismo:

    >>> x = [(1, 1), (2, 3), (1, 1), (5, 4), (2, 3)]
    >>> y = list(set(x))
    >>> y
    [(5, 4), (2, 3), (1, 1)]
    >>> 
    • Sí, el orden no es importante.La solución de la combinación de la lista + set es el que yo uso como ejemplo en el OP (que admito que es bastante ofuscado). El problema es que utiliza las listas, y por lo tanto la memoria utilizada es enorme, teniendo el mismo problema que si yo estaba trabajando sólo con listas en lugar de matrices desde el principio.

Dejar respuesta

Please enter your comment!
Please enter your name here