Numpy.searchsorted kullandıktan sonra sıralanmamış dizinleri bulun

ids büyük (milyonlarca) kimlik numarası dizisine sahibim ve ids <'de başka bir hedef dizisinin ( hedefleri ) bulunduğu dizinleri bulmak istiyorum/code> dizi. Örneğin, eğer

ids = [22, 5, 4, 0, 100]
targets = [5, 0]

sonra sonucu istiyorum:

>>> [1,3]

ids dizisini önceden sıralarsam, numpy.searchsorted , örneğin, kullanarak eşleşmeleri bulmak kolaydır.

>>> ids = np.array([22, 5, 4, 0, 100])
>>> targets = [5, 0]
>>> sort = np.argsort(ids)
>>> ids[sort]
[0,4,5,22,100]
>>> np.searchsorted(ids, targets, sorter=sort)
[2,0]

Ancak, bu sonucu 'çözmek' için ters eşlemeyi nasıl bulabilirim? Yani [2,0] 'daki sıralı girişleri daha önce bulundukları yerlerle eşleştirmek için: [1,3] .

5
@ atomh33ls gotcha, teşekkürler!
katma yazar DilithiumMatrix, kaynak
Kodunuz yalnızca satır 1 için ids = np.array ([22, 5, 4, 0, 100]) kullandığımda çalıştı.
katma yazar atomh33ls, kaynak
Aslında benim için ids [sort] konumunda başarısız oluyor
katma yazar atomh33ls, kaynak

8 cevap

Bunun etrafında dans eden birkaç cevap var, fakat tek yapmanız gereken tek yapmanız gereken sort [rank] 'ı kullanmak.

# Setup
ids = np.array([22, 5, 4, 0, 100])
targets = np.array([5, 0])

sort = np.argsort(ids)
rank = np.searchsorted(ids, targets, sorter=sort)
print(sort[rank])
# array([1, 3])
6
katma
Bu gerçekten önemli değil, ama bu benim cevabım ile aynı değil mi?
katma yazar atomh33ls, kaynak

Bunun etrafında dans eden birkaç cevap var, fakat tek yapmanız gereken tek yapmanız gereken sort [rank] 'ı kullanmak.

# Setup
ids = np.array([22, 5, 4, 0, 100])
targets = np.array([5, 0])

sort = np.argsort(ids)
rank = np.searchsorted(ids, targets, sorter=sort)
print(sort[rank])
# array([1, 3])
6
katma
Bu gerçekten önemli değil, ama bu benim cevabım ile aynı değil mi?
katma yazar atomh33ls, kaynak

Bunu sadece yapabilir misin?

sort[np.searchsorted(ids, targets, sorter=sort)]

Alternatif:

np.hstack([np.where(ids==x)[0] for x in targets])

her ikisi de:

array([1, 3])
2
katma
Bu işe yarıyor, fakat sadece değere göre değer aramakla aynı - bu çok yavaş olacak
katma yazar DilithiumMatrix, kaynak
@zhermes Fuar noktası!
katma yazar atomh33ls, kaynak

Bunu sadece yapabilir misin?

sort[np.searchsorted(ids, targets, sorter=sort)]

Alternatif:

np.hstack([np.where(ids==x)[0] for x in targets])

her ikisi de:

array([1, 3])
2
katma
Bu işe yarıyor, fakat sadece değere göre değer aramakla aynı - bu çok yavaş olacak
katma yazar DilithiumMatrix, kaynak
@zhermes Fuar noktası!
katma yazar atomh33ls, kaynak

Galiba bir şey buldum.

We can construct a 'cipher' or sorts: key = numpy.arange(len(ids)) applying the initial sorter to this key then gives the reverse mapping: revsort = key[np.argsort(ids)]


edit: @birico işaret ettiği gibi, tuşu [sort] sort ile aynıdır!

>>> sort = np.argsort(ids)
>>> ids[sort]
[0,4,5,22,100]
>>> found = np.searchsorted(ids, targets, sorter=sort)
>>> found
[2,0]
>>> sort[found]
[1,3]
1
katma
key [sort] her zaman sort ile tamamen aynı olacaktır.
katma yazar Bi Rico, kaynak

Galiba bir şey buldum.

We can construct a 'cipher' or sorts: key = numpy.arange(len(ids)) applying the initial sorter to this key then gives the reverse mapping: revsort = key[np.argsort(ids)]


edit: @birico işaret ettiği gibi, tuşu [sort] sort ile aynıdır!

>>> sort = np.argsort(ids)
>>> ids[sort]
[0,4,5,22,100]
>>> found = np.searchsorted(ids, targets, sorter=sort)
>>> found
[2,0]
>>> sort[found]
[1,3]
1
katma
key [sort] her zaman sort ile tamamen aynı olacaktır.
katma yazar Bi Rico, kaynak

Burada yayın ’ı kullanabilirsiniz. bir astar -

_,out = np.where(np.array(ids)==np.array(targets)[:,None])

Örnek çalışma -

In [20]: ids
Out[20]: [22, 5, 4, 0, 100]

In [21]: targets
Out[21]: [0, 22, 5]

In [22]: _,out = np.where(np.array(ids)==np.array(targets)[:,None])

In [23]: out
Out[23]: array([3, 0, 1], dtype=int64)
0
katma
@Divakar emin, açık bir döngü yok, ancak hız temelde bir döngü ile aynı olmaz mı? Ve hafıza kullanımı biraz daha kötü?
katma yazar DilithiumMatrix, kaynak
İlginç bir yaklaşım, ancak bu miktarı @ atomh33ls'ın önerdiği gibi yapmıyorum ---- hala değere göre bir arama değeri yapmakla bitiyor?
katma yazar DilithiumMatrix, kaynak
@DSM broadcasting ile yeni bir yaklaşım eklendi.
katma yazar Divakar, kaynak
@zhermes Hızdan emin değilsiniz, ancak belleğe biraz daha ihtiyaç duyulacaktı.
katma yazar Divakar, kaynak
@zhermes Eh, yayınla diğer cevapta kullanılan döngüden kaçınıyorum.
katma yazar Divakar, kaynak
@ DSM Ah evet, sipariş bilgileri kaybedilecek.
katma yazar Divakar, kaynak
Bunun işe yarayacağından emin değilim. hedeflerini tersine çevirirseniz, yine de [1,3] çıkışını alırsınız; sipariş bilgilerini kullanmıyorsunuz. IOW, karşılık gelen endeksleri değil katılan endeksleri alırsınız.
katma yazar DSM, kaynak

Burada yayın ’ı kullanabilirsiniz. bir astar -

_,out = np.where(np.array(ids)==np.array(targets)[:,None])

Örnek çalışma -

In [20]: ids
Out[20]: [22, 5, 4, 0, 100]

In [21]: targets
Out[21]: [0, 22, 5]

In [22]: _,out = np.where(np.array(ids)==np.array(targets)[:,None])

In [23]: out
Out[23]: array([3, 0, 1], dtype=int64)
0
katma
@Divakar emin, açık bir döngü yok, ancak hız temelde bir döngü ile aynı olmaz mı? Ve hafıza kullanımı biraz daha kötü?
katma yazar DilithiumMatrix, kaynak
İlginç bir yaklaşım, ancak bu miktarı @ atomh33ls'ın önerdiği gibi yapmıyorum ---- hala değere göre bir arama değeri yapmakla bitiyor?
katma yazar DilithiumMatrix, kaynak
@zhermes Hızdan emin değilsiniz, ancak belleğe biraz daha ihtiyaç duyulacaktı.
katma yazar Divakar, kaynak
@zhermes Eh, yayınla diğer cevapta kullanılan döngüden kaçınıyorum.
katma yazar Divakar, kaynak
@DSM broadcasting ile yeni bir yaklaşım eklendi.
katma yazar Divakar, kaynak
@ DSM Ah evet, sipariş bilgileri kaybedilecek.
katma yazar Divakar, kaynak
Bunun işe yarayacağından emin değilim. hedeflerini tersine çevirirseniz, yine de [1,3] çıkışını alırsınız; sipariş bilgilerini kullanmıyorsunuz. IOW, karşılık gelen endeksleri değil katılan endeksleri alırsınız.
katma yazar DSM, kaynak