Numpy: python3: regresión para matrices únicas en dtype = object con diferentes tipos de elementos (Trac # 2188)

Creado en 19 oct. 2012  ·  18Comentarios  ·  Fuente: numpy/numpy

_Boleto original http://projects.scipy.org/numpy/ticket/2188 el 2012-07-23 por @yarikoptic , asignado a unknown._

probado contra el maestro actual (presente en 1.6.2 también):

Si con la serie python2.x funciona bien, sin vomitar:

$> python2.7 -c 'import numpy as np; print repr(repr(np.unique(np.array([1,2, None, "str"]))))' 
'array([None, 1, 2, str], dtype=object)'

NB: Informaré un error en la reproducción aquí por separado si aún no se ha presentado

falla con python3.x por completo:

$> python3.2 -c 'import numpy as np; print(repr(repr(np.unique(np.array([1,2,None, "str"])))))'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.2/dist-packages/numpy/lib/arraysetops.py", line 194, in unique
    ar.sort()
TypeError: unorderable types: int() > NoneType()

siempre que en mi humilde opinión debe funcionar correctamente: la semántica de la acción única () no debe implicar la capacidad de ordenar los elementos

00 - Bug numpy.core

Comentario más útil

¿Alguna actualización sobre esto? Me encontré con este error al intentar utilizar scikit-learn de LabelEncoder de pandas trama de datos con columnas dtype "objeto" y los valores perdidos

Todos 18 comentarios

¿Alguna idea nueva sobre este tema?

Las únicas opciones para implementar unique son:

  • ordenar la matriz
  • poniendo todo en una tabla hash
  • hacer una comparación de fuerza bruta == en todos los objetos contra todos los objetos

Solo las estrategias de ordenación y hash tienen una velocidad razonable, y solo las estrategias de ordenación y todos contra todos tienen una sobrecarga de memoria razonable para arreglos grandes. Entonces, supongo que podríamos agregar opciones de respaldo a las únicas en las que, si la clasificación no funciona, ¿intenta una de las otras estrategias? Pero OTOH no es bueno tener una función que a veces de repente consume mas CPU o memoria dependiendo de la entrada que le des.

Supongo que haría +1 en un parche que agregue una opción de estrategia = {"sort", "hash", "fuerza bruta"} a np.unique, para que los usuarios con datos extraños puedan decidir qué tiene sentido para su situación. Si quieres escribir algo así :-)

al principio, me preguntaba si podría ser ordenar + tabla hash para elementos que no se pueden ordenar (no verifiqué si se usa cmp de elementos al ordenar elementos de la matriz de objetos dtype), por lo que ordenar __cmp__ podría colocarlos en 'por orden de llegada -primera orden en línea?
pero luego me di cuenta de que no proporciona un alivio en general para tipos incomparables, por ejemplo, cuando es una mezcla de int y str ... así que me pregunté si para dtype = object podría ser factible deducir los primeros dtypes participantes y 'unique '(posiblemente vía sort) dentro de cada dtype posiblemente confiando en tablas hash para dtypes sin __cmp__ ?

solo para aquellos que puedan necesitar una solución alternativa, así es como lo hago a través de 'hash' a través de los conjuntos integrados para mi caso:

$> python3.3 -c 'import numpy as np; print(np.array(list(set([1,2,"str", None])), dtype=object))' 
[None 1 2 'str']

No estoy seguro de lo que acaba de decir :-)

Pero pensándolo bien, la clasificación no es realmente confiable para dtype = object
de todas formas. Probablemente he escrito docenas de clases que anulan la ecuación pero
mantener el lt predeterminado, lo que significa que el único basado en clasificación
devuelve silenciosamente la respuesta incorrecta. Este es un error bastante desagradable, supongo.

Si los objetos son hash, puede hacer set (arr) para obtener el único
elementos, pero no hay garantía de que sean hash en general. (Pero al menos
todos que para objetos hash esto debería _funcionar_, lo cual no es cierto
para ordenar.) Quizás esta sería una mejor implementación predeterminada de
np.unique para matrices de objetos.

El martes, 17 de septiembre de 2013 a las 5:40 p.m., Yaroslav Halchenko <
[email protected]> escribió:

al principio me preguntaba si podría ser ordenar + tabla hash para insortable
elementos (no verifiqué si se usa _cmp_ de elementos al ordenar elementos de
dtype object array) por lo que ordenar cmp podría colocarlos en
orden de "primero en llegar primero en línea"?
pero luego se dio cuenta de que no proporciona un alivio en general para
tipos incomparables, por ejemplo, cuando es una mezcla de int y str ... así que me preguntaba
si para dtype = object podría ser factible deducir el primer participante
dtypes y 'único' (posiblemente a través de clasificación) dentro de cada dtype posiblemente confiando
en tablas hash para dtypes sin cmp ?

-
Responda a este correo electrónico directamente o véalo en Gi
.

gy ... ok - descripción cruel en Python:

def bucketed_unique(a):
    buckets = {}
    for x in a:
        t = type(x)
        if not (t in buckets):
            buckets[t] = bucket = []
        else:
            bucket = buckets[t]
        bucket.append(x)
    out = []
    for bucket in buckets.itervalues():
        # here could be actually set of conditions instead of blind try/except
        try:
            out.append(np.unique(bucket))
        except:
            out.append(np.array(list(set(bucket)), dtype=object))
    return np.hstack(out)
print bucketed_unique([1, 2, 'str', None, np.nan, None, np.inf, int])
[1 2 'str' None <type 'int'> nan inf]

Cosa segura: no se debe hacer ningún 'agrupamiento' para los ndarrays que no son objetos

Ese algoritmo no usa == como su definición de unicidad. Objetos de
diferentes tipos pueden ser ==. (Ejemplo sencillo: 1, 1.0). Su definición no
corresponden a cualquier concepto estándar de Python.
El 17 de septiembre de 2013 a las 18:01, "Yaroslav Halchenko" [email protected] escribió:

Cosa segura: no se debe hacer ningún 'agrupamiento' para los ndarrays que no son objetos

-
Responda a este correo electrónico directamente o véalo en Gi
.

¡en efecto! No estoy seguro, pero puede ser que un análisis post-hoc a través de grupos tendría sentido ... por cierto, el problema atm se revela también para la comparación con números complejos:

$> python3.3 -c 'import numpy as np; print(np.unique(np.array([1, 1.0, 1+0j], dtype=object)))'  
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 194, in unique
    ar.sort()
TypeError: unorderable types: float() > complex()

$> python -c 'import numpy as np; print(np.unique(np.array([1, 1.0, 1+0j], dtype=object)))' 
[1]

aunque en el segundo pensamiento, ¿cuál debería ser el valor 'único' dtype entre todas las opciones disponibles (int / float / complex)? con una matriz que no es de objetos, está claro ... con una matriz de objetos heterogéneos, no es así, incluso puede haber diferentes tipos de dtipos que deben mantenerse como tales ...

Así es como resolví argsort explotando en int / str mixtos en py3: https://github.com/pydata/pandas/pull/6222/files

ordenar las entradas antes de las cadenas en tipos de objetos
use una tabla hash para mapear las ubicaciones para obtener el indexador
razonablemente rápido, creo

usa la implementación de pandas hashtable, pero creo que podría intercambiarse / adaptarse fácilmente al código c

¿Alguien quiere darle un giro a esto? No estoy seguro de qué hacer con los tipos de registros.

¿Alguna actualización sobre esto? Me encontré con este error al intentar utilizar scikit-learn de LabelEncoder de pandas trama de datos con columnas dtype "objeto" y los valores perdidos

Este es muy viejo. ¿Sigue siendo relevante?

parece ser el caso al menos con 1.15.4 en debian:

$> python3 --version
Python 3.6.5

$> PYTHONPATH=.. python3 -c 'import numpy as np; print(np.__version__); print(repr(repr(np.unique(np.array([1,2,None, "str"])))))'                                                                                   
1.15.4
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 233, in unique
    ret = _unique1d(ar, return_index, return_inverse, return_counts)
  File "/usr/lib/python3/dist-packages/numpy/lib/arraysetops.py", line 281, in _unique1d
    ar.sort()
TypeError: '<' not supported between instances of 'NoneType' and 'int'

Definitivamente sigue siendo relevante. Me encontré con esto, tratando de llamar a np.unique(x, return_inverse=True) en una matriz de objetos.

En cuanto a la cuestión de _cómo_ hacer que esto funcione, cuando la clasificación no está definida: preferiría un algoritmo lento al status quo de generar un error. (En mi experiencia, a menudo, si necesita algoritmos de rendimiento, no debería usar una matriz de objetos para empezar).

Creo que esta es una solicitud de función, no un error. Los documentos dicen claramente:

Devuelve los elementos únicos _ordenados_ de una matriz.

Para el caso de una matriz como [1, None] , no existe tal matriz ordenada en Python 3 ya que la ordenación ya no está bien definida.

Sería bueno tener una opción para _no_ devolver una matriz ordenada, permitiría algunas optimizaciones.

¿Fue útil esta página
0 / 5 - 0 calificaciones