Eliminar filas duplicadas de una matriz numpy [duplicate]

3 minutos de lectura

avatar de usuario
romano

¿Cómo puedo eliminar filas duplicadas de un 2 dimensional numpy ¿formación?

data = np.array([[1,8,3,3,4],
                 [1,8,9,9,4],
                 [1,8,3,3,4]])

La respuesta debería ser la siguiente:

ans = array([[1,8,3,3,4],
             [1,8,9,9,4]])

Si hay dos filas que son iguales, me gustaría eliminar una fila “duplicada”.

  • ¿Está bien si las filas no están en ese orden originalmente presentes en la matriz de entrada?

    – Divakar

    28 de junio de 2015 a las 7:39

  • si, el orden no es importante

    – romano

    28 de junio de 2015 a las 7:40

  • Mi problema es muy parecido al tuyo. [Look here][1] [1]: stackoverflow.com/questions/31093261/…

    -Simone Bolognini

    28 de junio de 2015 a las 7:42

  • Creo que ahora puedes aplicar np.unique sobre un eje, entonces np.unique(data, axis = 0) obras.

    – Austin Garret

    30 de enero de 2018 a las 20:57


avatar de usuario
Srivatsan

Puedes usar numpy unique. Como desea las filas únicas, debemos ponerlas en tuplas:

import numpy as np

data = np.array([[1,8,3,3,4],
                 [1,8,9,9,4],
                 [1,8,3,3,4]])

solo aplicando np.unique hacia data matriz resultará en esto:

>>> uniques
array([1, 3, 4, 8, 9])

imprime los elementos únicos en la lista. Entonces ponerlos en tuplas da como resultado:

new_array = [tuple(row) for row in data]
uniques = np.unique(new_array)

que imprime:

>>> uniques
array([[1, 8, 3, 3, 4],
       [1, 8, 9, 9, 4]])

ACTUALIZAR

En la nueva versión, debe configurar np.unique(data, axis=0)

  • Lo intenté new_array = [tuple(row) for row in data] uniques = np.unique(new_array) pero aún genera únicos array([1, 3, 4, 8, 9]) @El depredador

    – Owen

    27 de junio de 2016 a las 3:33


  • @Owen: Eso no puede ser posible, revisa tu código una vez más.

    – Srivatsan

    27 de junio de 2016 a las 8:25

  • Aquí está el código, usé el mismo código que tu programa: import numpy as np data = np.array([[1,8,3,3,4], [1,8,9,9,4], [1,8,3,3,4]]) new_array = [tuple(row) for row in data] uniques = np.unique(new_array) uniques Out[30]: array([1, 3, 4, 8, 9]) ¿Es eso algo sobre la versión numpy? mi versión numpy es 1.9.2

    – Owen

    27 de junio de 2016 a las 14:18


  • Creo que la siguiente es la respuesta correcta stackoverflow.com/questions/16970982/…

    – TommasoF

    12 de abril de 2017 a las 17:22

  • En la nueva versión, debe configurar np.unique(data, axis=0)

    – Tal como

    28 de mayo de 2019 a las 0:40

avatar de usuario
Divakar

Un enfoque con lex-sorting

# Perform lex sort and get sorted data
sorted_idx = np.lexsort(data.T)
sorted_data =  data[sorted_idx,:]

# Get unique row mask
row_mask = np.append([True],np.any(np.diff(sorted_data,axis=0),1))

# Get unique rows
out = sorted_data[row_mask]

Ejecución de muestra –

In [199]: data
Out[199]: 
array([[1, 8, 3, 3, 4],
       [1, 8, 9, 9, 4],
       [1, 8, 3, 3, 4],
       [1, 8, 3, 3, 4],
       [1, 8, 0, 3, 4],
       [1, 8, 9, 9, 4]])

In [200]: sorted_idx = np.lexsort(data.T)
     ...: sorted_data =  data[sorted_idx,:]
     ...: row_mask = np.append([True],np.any(np.diff(sorted_data,axis=0),1))
     ...: out = sorted_data[row_mask]
     ...: 

In [201]: out
Out[201]: 
array([[1, 8, 0, 3, 4],
       [1, 8, 3, 3, 4],
       [1, 8, 9, 9, 4]])

Pruebas de tiempo de ejecución –

Esta sección cronometra todos los enfoques propuestos en las soluciones presentadas hasta ahora.

In [34]: data = np.random.randint(0,10,(10000,10))

In [35]: def tuple_based(data):
    ...:     new_array = [tuple(row) for row in data]
    ...:     return np.unique(new_array)
    ...: 
    ...: def lexsort_based(data):                 
    ...:     sorted_data =  data[np.lexsort(data.T),:]
    ...:     row_mask = np.append([True],np.any(np.diff(sorted_data,axis=0),1))
    ...:     return sorted_data[row_mask]
    ...: 
    ...: def unique_based(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]))
    ...: 

In [36]: %timeit tuple_based(data)
10 loops, best of 3: 63.1 ms per loop

In [37]: %timeit lexsort_based(data)
100 loops, best of 3: 8.92 ms per loop

In [38]: %timeit unique_based(data)
10 loops, best of 3: 29.1 ms per loop

  • para tu información: unique_based es aproximadamente el doble de rápido que np.unique(data, axis=0)por lo que lexsort sigue siendo preferible en 2022.

    – Marius Wallraff

    22 de julio a las 14:17

avatar de usuario
omerbp

Una solución sencilla puede ser:

import numpy as np
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]))

data = np.array([[1,8,3,3,4],
                 [1,8,9,9,4],
                 [1,8,3,3,4]])


print unique_rows(data)
#prints:
[[1 8 3 3 4]
 [1 8 9 9 4]]

Puede consultar esto para obtener muchas más soluciones para este problema.

¿Ha sido útil esta solución?