Python

2010-10-27 7 views
16

içinde numpy/scipy dizisindeki benzersiz öğeleri saymanın etkili yolu Bir scipy dizim var, ör.Python

a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]]) 

Dizideki her benzersiz öğenin gerçekleştirilme sayısını saymak istiyorum. Örneğin, yukarıdaki dizi için a, [0, 0, 1], [1, 1, 1] ve 1 [1, 0, 1] 1 oluşumunun 1 meydana geldiğini öğrenmek istiyorum.

from collections import defaultdict 
d = defaultdict(int) 

for elt in a: 
    d[elt] += 1 

daha iyi/daha verimli bir yolu yoktur:

bir yolu ben öyle yapmayı düşündün mü?

Teşekkürler.

+0

? Ya da bu sadece bu fikri çözmek için bir Numpy/Scipy işlevine sahip olmak isteyen mi? – Zelphir

cevap

8

Python 2.7 (veya 3.1) ile yapışmasını bir sorun değildir ve bu iki Python sürümleri herhangi Eğer küpe gibi unsurları hashable sopa eğer belki yeni collections.Counter sizin için bir şey olabilir, sizin için kullanılabilir ise:

>>> from collections import Counter 
>>> c = Counter([(0,0,1), (1,1,1), (1,1,1), (1,0,1)]) 
>>> c 
Counter({(1, 1, 1): 2, (0, 0, 1): 1, (1, 0, 1): 1})

Bu iki yaklaşımla ilgili herhangi bir performans testi gerçekleştirmedim. piton için

+5

varsayılan olarak daha hızlı olacaktır. John Machin bunu bugün erken saatlerde bir cevapla gösterdi (http://stackoverflow.com/questions/4036474/add-new-keys-to-a-dictionary-while-incrementing-existing-values). –

+0

Bilmekte fayda var :-) Teşekkürler :-) –

+1

OP başlığının istediği gibi, Numpy/Scipy kullanmaz. Ayrıca, Python'un eski sürümlerinin kullanımını da savunmaktadır. Bunun iyi bir cevap olduğundan emin değilim. – Zelphir

1

2,6 <

import itertools 

data_array = [[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]] 

dict_ = {} 

for list_, count in itertools.groupby(data_array): 
    dict_.update({tuple(list_), len(list(count))}) 
Sen satırlara göre sözlük sırasında dizi ve satırları değiştirmek noktaları için göz sıralayabilirsiniz
4

:

In [1]: a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]]) 

In [2]: b = a[lexsort(a.T)] 

In [3]: b 
Out[3]: 
array([[0, 0, 1], 
     [1, 0, 1], 
     [1, 1, 1], 
     [1, 1, 1]]) 

... 


In [5]: (b[1:] - b[:-1]).any(-1) 
Out[5]: array([ True, True, False], dtype=bool) 

son dizisi ilk üç satırı farklılık gösterdiğini söylüyor ve üçüncü sıra iki kere tekrarlanır.

birler ve sıfırlar diziler için değerleri kodlayabilirsiniz:

In [6]: bincount(dot(a, array([4,2,1]))) 
Out[6]: array([0, 1, 0, 0, 0, 1, 0, 2]) 

Sözlükler de kullanılabilir. Çeşitli yöntemlerden hangisinin en hızlı olacağı, aslında üzerinde çalıştığınız dizilere bağlı olacaktır.

0

numpy_indexed paketi (uyarı: Ben onun yazarım) mandrendeki yayınlanmıştır benzer bir çözüm sağlar; güzel bir vectorized olanıdır. Ama testler, güzel bir arayüz ve daha birçok ilgili kullanışlı fonksiyonları ile:

senin örneğin kodda Numpy/scipy kullanımıdır
import numpy_indexed as npi 
npi.count(a)