Numpy: python3: regresi untuk unik pada dtype = array objek dengan berbagai jenis item (Trac # 2188)

Dibuat pada 19 Okt 2012  ·  18Komentar  ·  Sumber: numpy/numpy

_Tiket asli http://projects.scipy.org/numpy/ticket/2188 pada tanggal 23-07-2012 oleh

diuji terhadap master saat ini (hadir dalam 1.6.2 juga):

Jika dengan seri python2.x berfungsi dengan baik, tanpa muntah:

$> 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 Saya akan melaporkan bug pada repr di sini secara terpisah jika belum diajukan

itu gagal dengan python3.x sama sekali:

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

setiap kali IMHO itu harus beroperasi dengan benar - semantik tindakan unique () tidak boleh menyiratkan kemampuan untuk mengurutkan elemen

00 - Bug numpy.core

Komentar yang paling membantu

Ada pembaruan tentang ini? Saya mengalami bug ini ketika mencoba untuk menggunakan scikit-belajar ini LabelEncoder pada panda DataFrame kolom dengan dtype "objek" dan nilai-nilai yang hilang

Semua 18 komentar

ada ide segar tentang masalah ini?

Opsi satu-satunya untuk menerapkan unique adalah:

  • mengurutkan array
  • meletakkan semuanya di tabel hash
  • lakukan perbandingan brute-force == pada semua objek terhadap semua objek

Hanya strategi penyortiran dan hashing yang memiliki kecepatan yang wajar, dan hanya strategi penyortiran dan strategi all-against-all yang memiliki overhead memori yang wajar untuk array besar. Jadi saya kira kita bisa menambahkan opsi fallback ke unique di mana jika penyortiran tidak berhasil maka mencoba salah satu strategi lain? Tapi OTOH tidak menyenangkan memiliki fungsi yang terkadang tiba-tiba membutuhkan lebih banyak CPU atau memori tergantung pada masukan apa yang Anda berikan.

Saya kira saya akan memberi +1 pada tambalan yang menambahkan opsi strategi = {"sort", "hash", "bruteforce"} ke np.unique, sehingga pengguna dengan data aneh dapat memutuskan apa yang masuk akal untuk situasi mereka. Jika Anda ingin menulis hal seperti itu :-)

pada awalnya saya bertanya-tanya apakah itu bisa menyortir + tabel hash untuk item yang tidak dapat disortir (tidak memeriksa apakah cmp elemen digunakan saat menyortir elemen larik objek dtype) jadi menyortir __cmp__ dapat memposisikannya di 'first-come -pertama-dalam-baris '?
tetapi kemudian menyadari bahwa itu tidak memberikan bantuan secara umum untuk tipe yang tidak dapat dibandingkan, misalnya ketika itu adalah campuran dari int dan str ... jadi saya bertanya-tanya apakah untuk dtype = object dapat layak untuk menyimpulkan dtypes yang berpartisipasi pertama dan 'unik '(mungkin melalui sort) dalam setiap dtype mungkin mengandalkan tabel hash untuk dtypes tanpa __cmp__ ?

hanya untuk mereka yang mungkin membutuhkan solusi, berikut adalah cara saya melakukannya melalui 'hashing' melalui set bawaan untuk kasus saya:

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

Tidak yakin apa yang baru saja Anda katakan :-)

Tetapi pada pemikiran lebih lanjut, penyortiran benar-benar tidak dapat diandalkan untuk dtype = object
bagaimanapun. Saya mungkin telah menulis lusinan kelas yang menimpa eq tetapi
pertahankan lt default, yang berarti bahwa unik berbasis sortir hanya akan
diam-diam mengembalikan jawaban yang salah. Ini adalah bug yang cukup buruk kurasa.

Jika objeknya hashable maka Anda bisa melakukan set (arr) untuk mendapatkan unique
elemen, tetapi tidak ada jaminan bahwa mereka dapat di-hash secara umum. (Tapi setidaknya
setiap orang yang untuk objek hashable ini harus _work_, yang tidak benar
untuk penyortiran.) Mungkin ini akan menjadi implementasi default yang lebih baik dari
np.unique untuk array objek.

Pada hari Selasa, 17 Sep 2013 jam 17:40, Yaroslav Halchenko <
[email protected]> menulis:

pada awalnya saya bertanya-tanya apakah itu bisa menyortir + tabel hash untuk unsortable
item (tidak memeriksa apakah _cmp_ elemen digunakan saat menyortir elemen
dtype object array) sehingga pengurutan cmp dapat memposisikannya
'urutan pertama datang pertama di baris'?
tetapi kemudian menyadari bahwa hal itu tidak memberikan kelegaan secara umum
tipe yang tidak bisa dibandingkan, misalnya ketika itu adalah campuran int dan str ... jadi saya bertanya-tanya
jika untuk dtype = objek itu bisa layak untuk disimpulkan pertama kali berpartisipasi
dtypes dan 'unique' (mungkin melalui sort) dalam setiap dtype mungkin mengandalkan
pada tabel hash untuk dtypes tanpa cmp ?

-
Balas email ini secara langsung atau lihat di Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24603047
.

gy ... ok - deskripsi kejam dengan 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]

hal yang pasti - tidak ada 'bucketing' yang harus dilakukan untuk ndarrays non-objek

Algoritme itu tidak menggunakan == sebagai definisi keunikannya. Objek dari
jenis yang berbeda dapat ==. (Contoh mudah: 1, 1.0). Definisinya tidak
sesuai dengan konsep python standar.
Pada 17 Sep 2013 18:01, "Yaroslav Halchenko" [email protected] menulis:

hal yang pasti - tidak ada 'bucketing' yang harus dilakukan untuk ndarrays non-objek

-
Balas email ini secara langsung atau lihat di Gi tHubhttps: //github.com/numpy/numpy/issues/641#issuecomment -24604740
.

memang! tidak yakin tetapi mungkin analisis post-hoc lintas kelompok akan masuk akal ... btw masalah atm mengungkapkan dirinya juga untuk perbandingan dengan bilangan kompleks:

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

meskipun pada pemikiran ke-2 - apa yang harus dtype nilai 'unik' kemudian menjadi di antara semua pilihan yang tersedia (int / float / complex)? dengan array non-objek jelas ... dengan array objek heterogen, tidak begitu - bahkan mungkin tipe yang berbeda harus dipertahankan seperti itu ...

Inilah cara saya menyelesaikan argsort meledakkan campuran int / str di py3: https://github.com/pydata/pandas/pull/6222/files

pesan int sebelum string dalam dtypes objek
gunakan hashtable untuk memetakan lokasi untuk mendapatkan pengindeks
cukup cepat menurut saya

menggunakan implementasi hashtable panda tetapi saya pikir dapat dengan mudah ditukar / disesuaikan dengan kode-c

Ada yang mau mencoba ini? Tidak yakin apa yang harus dilakukan dengan tipe record.

Ada pembaruan tentang ini? Saya mengalami bug ini ketika mencoba untuk menggunakan scikit-belajar ini LabelEncoder pada panda DataFrame kolom dengan dtype "objek" dan nilai-nilai yang hilang

Yang ini sangat tua. Apakah masih relevan?

tampaknya menjadi kasus setidaknya dengan 1.15.4 di 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'

Pasti masih relevan. Baru saja menemukan ini, mencoba memanggil np.unique(x, return_inverse=True) pada larik objek.

Mengenai pertanyaan _bagaimana_ membuat ini berfungsi, saat pengurutan tidak ditentukan: Saya lebih memilih algoritme yang lambat daripada status quo untuk meningkatkan kesalahan. (Dalam pengalaman saya, seringkali, jika Anda membutuhkan algoritme yang berkinerja baik, Anda tidak boleh menggunakan larik objek untuk memulai.)

Saya rasa ini adalah permintaan fitur, bukan bug. Dokumen tersebut dengan jelas menyatakan:

Mengembalikan elemen unik _sorted_ dari larik.

Untuk kasus array seperti [1, None] , tidak ada array yang diurutkan seperti itu di python 3 karena penyortiran tidak lagi terdefinisi dengan baik.

Alangkah baiknya memiliki opsi untuk _not_ mengembalikan array yang diurutkan, ini akan memungkinkan beberapa pengoptimalan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

kevinzhai80 picture kevinzhai80  ·  4Komentar

Kreol64 picture Kreol64  ·  3Komentar

toddrjen picture toddrjen  ·  4Komentar

keithbriggs picture keithbriggs  ·  3Komentar

amuresan picture amuresan  ·  4Komentar