Numpy: python3: regressão para matrizes únicas em dtype = objeto com vários tipos de itens (Trac # 2188)

Criado em 19 out. 2012  ·  18Comentários  ·  Fonte: numpy/numpy

_Tíquete original http://projects.scipy.org/numpy/ticket/2188 em 2012-07-23 por @yarikoptic , atribuído a desconhecido._

testado contra o mestre atual (presente em 1.6.2 também):

Se com a série python2.x funcionar bem, sem 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, vou relatar um bug no repr aqui separadamente, se ainda não for arquivado

ele falha com python3.x completamente:

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

sempre que IMHO deve operar corretamente - semântica de ação única () não deve implicar capacidade de ordenar os elementos

00 - Bug numpy.core

Comentários muito úteis

Alguma atualização sobre isso? Encontrei esse bug ao tentar usar o LabelEncoder do

Todos 18 comentários

alguma ideia nova sobre este assunto?

As únicas opções para implementar unique são:

  • classificando a matriz
  • colocando tudo em uma mesa de hash
  • fazer comparação de força bruta == em todos os objetos contra todos os objetos

Apenas as estratégias de classificação e hashing têm velocidade razoável, e apenas as estratégias de classificação e todos contra todos têm sobrecarga de memória razoável para grandes arrays. Então, acho que poderíamos adicionar opções de fallback a exclusivo, se a classificação não funcionar, então ele tenta uma das outras estratégias? Mas OTOH não é bom ter uma função que às vezes de repente consome muito mais CPU ou memória, dependendo da entrada que você fornece.

Acho que receberia +1 em um patch que adiciona uma opção strategy = {"sort", "hash", "bruteforce"} ao np.unique, para que usuários com dados estranhos possam decidir o que faz sentido para sua situação. Se você quiser escrever tal coisa :-)

a princípio eu me perguntei se poderia ser classificação + tabela de hash para itens não classificáveis ​​(não verifiquei se cmp de elementos é usado ao classificar elementos da matriz de objeto dtype), portanto, classificar __cmp__ poderia posicioná-los na ordem -primeiro pedido in-line '?
mas então percebi que não fornece um alívio em geral para tipos incomparáveis, por exemplo, quando é uma mistura de int e str ... então eu me perguntei se para dtype = object seria viável deduzir os primeiros dtypes participantes e 'único '(possivelmente via sort) dentro de cada dtype possivelmente contando com tabelas hash para dtypes sem __cmp__ ?

apenas para aqueles que precisam de uma solução alternativa, aqui está como faço isso por meio de 'hashing' por meio dos conjuntos integrados para o meu caso:

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

Não tenho certeza do que você acabou de dizer :-)

Mas pensando melhor, a classificação não é realmente confiável para dtype = objeto
de qualquer forma. Provavelmente escrevi dezenas de classes que substituem eq, mas
manter o padrão lt , o que significa que o único baseado em classificação irá apenas
silenciosamente retorne a resposta errada. Este é um bug bem desagradável, eu acho.

Se os objetos são hashable, então você pode apenas fazer set (arr) para obter o único
elementos, mas nenhuma garantia de que eles sejam hashble em geral. (Mas pelo menos
todos que para objetos hashable isso deve _funcionar_, o que não é verdade
para classificação.) Talvez esta seja uma implementação padrão melhor de
np.unique para matrizes de objetos.

Na terça, 17 de setembro de 2013 às 17:40, Yaroslav Halchenko <
notificaçõ[email protected]> escreveu:

no começo eu me perguntei se poderia ser classificação + tabela hash para não classificável
itens (não verificou se _cmp_ de elementos é usado ao classificar elementos de
dtype object array), portanto, a classificação cmp pode posicioná-los
pedido 'primeiro a chegar, primeiro na linha'?
mas então percebi que não fornece um alívio em geral para
tipos incomparáveis, por exemplo, quando é uma mistura de int e str ... então eu me perguntei
se para dtype = object, poderia ser viável deduzir a primeira participação
dtypes e 'único' (possivelmente via sort) dentro de cada dtype possivelmente dependendo
em tabelas de hash para dtypes sem cmp ?

-
Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24603047
.

gy ... ok - descrição cruel em 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]

com certeza - nenhum 'bucketing' deve ser feito para ndarrays sem objeto

Esse algoritmo não usa == como sua definição de exclusividade. Objetos de
diferentes tipos podem ser ==. (Exemplo fácil: 1, 1.0). Sua definição não
correspondem a qualquer conceito python padrão.
Em 17 de setembro de 2013 18:01, "Yaroslav Halchenko" [email protected] escreveu:

com certeza - nenhum 'bucketing' deve ser feito para ndarrays sem objeto

-
Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24604740
.

de fato! não tenho certeza, mas pode ser uma análise post-hoc entre intervalos faria sentido ... a propósito, o problema do atm se revela também para comparação com números complexos:

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

embora no segundo pensamento - qual deveria ser o dtype de valor 'único' entre todas as opções disponíveis (int / float / complex)? com array não-objeto é claro ... com array heterogêneo de objeto, não - podem até ser dtypes diferentes devem ser mantidos como tal ...

Esta é a maneira que resolvi argsort explodindo em int / str misto em py3: https://github.com/pydata/pandas/pull/6222/files

ordenar os ints antes das strings em tipos de objetos
use uma tabela de hash para mapear os locais para obter o indexador
razoavelmente rápido eu acho

usa implementação de hashtable do pandas, mas poderia ser facilmente trocado / adaptado para c-code, eu acho

Alguém quer dar uma tacada nisso? Não tenho certeza do que fazer com os tipos de registro.

Alguma atualização sobre isso? Encontrei esse bug ao tentar usar o LabelEncoder do

Este é muito antigo. Ainda é relevante?

parece ser o caso pelo menos com 1.15.4 no 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, ainda é relevante. Acabei de me deparar com isso, tentando chamar np.unique(x, return_inverse=True) em um array de objetos.

Em relação à questão de _como_ fazer isso funcionar, quando a classificação é indefinida: Eu prefiro um algoritmo lento ao invés do status quo de gerar um erro. (Na minha experiência, muitas vezes, se você precisa de algoritmos de desempenho, não deve usar uma matriz de objeto para começar.)

Acho que é uma solicitação de recurso, não um bug. Os documentos afirmam claramente:

Retorna os elementos _sorted_ únicos de uma matriz.

Para o caso de um array como [1, None] , nenhum array ordenado existe em python 3, pois a ordenação não está mais bem definida.

Seria bom ter a opção de _não_ retornar um array ordenado, isso permitiria algumas otimizações.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

marcocaccin picture marcocaccin  ·  4Comentários

Levstyle picture Levstyle  ·  3Comentários

qualiaa picture qualiaa  ·  3Comentários

keithbriggs picture keithbriggs  ·  3Comentários

astrofrog picture astrofrog  ·  4Comentários