Numpy: python3: régression pour les tableaux uniques sur dtype = object avec différents types d'éléments (Trac # 2188)

Créé le 19 oct. 2012  ·  18Commentaires  ·  Source: numpy/numpy

_Billet original http://projects.scipy.org/numpy/ticket/2188 le 23/07/2012 par

testé par rapport au maître actuel (également présent en 1.6.2):

Si avec la série python2.x cela fonctionne bien, sans vomir:

$> 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 Je rapporterai un bug sur la reprographie ici séparément s'il n'est pas encore déposé

il échoue complètement avec python3.x:

$> 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()

chaque fois à mon humble avis, il doit fonctionner correctement - la sémantique de l'action unique () ne doit pas impliquer la capacité de trier les éléments

00 - Bug numpy.core

Commentaire le plus utile

Des mises à jour à ce sujet? J'ai rencontré ce bogue en essayant d'utiliser le LabelEncoder de scikit-learn sur les

Tous les 18 commentaires

des idées nouvelles sur cette question?

Les seules options pour implémenter unique sont:

  • trier le tableau
  • mettre tout dans une table de hachage
  • faire == comparaison par force brute

Seules les stratégies de tri et de hachage ont une vitesse raisonnable, et seules les stratégies de tri et tout-contre-tout ont une surcharge de mémoire raisonnable pour les grands tableaux. Donc, je suppose que nous pourrions ajouter des options de secours à unique où si le tri ne fonctionne pas, il essaie l'une des autres stratégies? Mais OTOH ce n'est pas agréable d'avoir une fonction qui prend parfois beaucoup plus de CPU ou de mémoire en fonction de l'entrée que vous lui donnez.

Je suppose que je serais +1 sur un patch qui ajoute une option strategy = {"sort", "hash", "bruteforce"} à np.unique, afin que les utilisateurs avec des données étranges puissent décider de ce qui est logique pour leur situation. Si vous voulez écrire une telle chose :-)

au début, je me demandais si cela pouvait être un tri + table de hachage pour les éléments non triables (je n'ai pas vérifié si cmp d'éléments est utilisé lors du tri des éléments du tableau d'objets dtype) donc le tri __cmp__ pourrait les positionner sur 'premier arrivé -première commande en ligne?
mais je me suis alors rendu compte que cela n'apportait pas de soulagement en général pour les types incomparables, par exemple quand il s'agit d'un mélange de int et de str ... alors je me suis demandé si pour dtype = object, il serait possible de déduire les premiers dtypes participants et 'unique '(éventuellement via sort) au sein de chaque dtype en s'appuyant éventuellement sur des tables de hachage pour les dtypes sans __cmp__ ?

juste pour ceux qui pourraient avoir besoin d'une solution de contournement, voici comment je le fais via le `` hachage '' à travers les ensembles intégrés pour mon cas:

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

Je ne sais pas ce que vous venez de dire :-)

Mais après réflexion, le tri n'est vraiment pas fiable pour dtype = object
en tous cas. J'ai probablement écrit des dizaines de classes qui remplacent l' eq mais
conserver le lt par défaut, ce qui signifie que l'unique basé sur le tri sera simplement
renvoyer silencieusement la mauvaise réponse. C'est un bug assez méchant je suppose.

Si les objets sont hachables, vous pouvez simplement faire set (arr) pour obtenir l'unique
éléments, mais aucune garantie qu'ils sont hachables en général. (Mais au moins
tout le monde qui pour les objets hachables cela devrait _work_, ce qui n'est pas vrai
pour le tri.) Peut-être que ce serait une meilleure implémentation par défaut de
np.unique pour les tableaux d'objets.

Le mar 17 septembre 2013 à 17 h 40, Yaroslav Halchenko <
[email protected]> a écrit:

au début, je me demandais si cela pouvait être tri + table de hachage pour non triable
items (n'a pas vérifié si _cmp_ des éléments est utilisé lors du tri des éléments de
dtype object array) afin que le tri cmp puisse les positionner sur
Commande «premier arrivé, premier en ligne»?
mais s'est ensuite rendu compte que cela ne soulageait pas en général
types incomparables, par exemple quand il s'agit d'un mix int et str ... alors je me suis demandé
si pour dtype = object, il pourrait être possible de déduire la première participation
dtypes et 'unique' (éventuellement via tri) au sein de chaque dtype en s'appuyant éventuellement
sur les tables de hachage pour les dtypes sans cmp ?

-
Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24603047
.

gy ... ok - description cruelle 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]

chose sûre - aucun `` compartimentage '' ne devrait être fait pour les ndarrays non-objets

Cet algorithme n'utilise pas == comme sa définition d'unicité. Objets de
différents types peuvent être ==. (Exemple simple: 1, 1.0). Sa définition ne
correspondent à n'importe quel concept python standard.
Le 17 septembre 2013 à 18h01, "Yaroslav Halchenko" [email protected] a écrit:

chose sûre - aucun `` compartimentage '' ne devrait être fait pour les ndarrays non-objets

-
Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24604740
.

En effet! pas sûr, mais peut être une analyse post-hoc sur des compartiments aurait du sens ... btw atm problème se révèle également pour la comparaison avec des nombres complexes:

$> 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]

bien que sur la deuxième pensée - quelle devrait alors être la valeur «unique» dtype parmi tous les choix disponibles (int / float / complex)? avec un tableau non-objet, il est clair ... avec un tableau d'objets hétérogènes, pas si - peut être même différents dtypes doivent être maintenus en tant que tels ...

Voici comment j'ai résolu l'explosion de argsort sur un mélange int / str dans py3: https://github.com/pydata/pandas/pull/6222/files

ordonner les entiers avant les chaînes dans les types d'objets
utiliser une table de hachage pour mapper les emplacements afin d'obtenir l'indexeur
raisonnablement rapide je pense

utilise l'implémentation de la table de hachage pandas mais pourrait facilement être échangé / adapté au c-code, je pense

Quelqu'un veut-il jouer un rôle? Je ne sais pas quoi faire à propos des dtypes d'enregistrement.

Des mises à jour à ce sujet? J'ai rencontré ce bogue en essayant d'utiliser le LabelEncoder de scikit-learn sur les

Celui-ci est vraiment vieux. Est-ce toujours d'actualité?

semble être le cas au moins avec 1.15.4 dans 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'

Certainement toujours d'actualité. Je viens de tomber sur ceci, en essayant d'appeler np.unique(x, return_inverse=True) sur un tableau d'objets.

En ce qui concerne la question de savoir comment faire ce travail, lorsque le tri n'est pas défini: je préfère de loin un algorithme lent au statu quo de générer une erreur. (D'après mon expérience, souvent, si vous avez besoin d'algorithmes performants, vous ne devriez pas utiliser un tableau d'objets pour commencer.)

Je pense que c'est une demande de fonctionnalité, pas un bogue. Les documents indiquent clairement:

Renvoie les éléments uniques _sortis_ d'un tableau.

Pour le cas d'un tableau comme [1, None] , un tel tableau trié n'existe pas dans python 3 car le tri n'est plus bien défini.

Ce serait bien d'avoir une option pour _pas_ retourner un tableau trié, cela permettrait quelques optimisations.

Cette page vous a été utile?
0 / 5 - 0 notes