Apakah mereka selalu dipesan seperti dalam contoh itu?
Farinha
@ Peter. Ya, Anda sudah mengurutkan daftar untuk keperluan posting. Apakah daftar akan selalu disortir?
S.Lott
2
Tidak, daftar tidak akan selalu diurutkan. Ini bukan pekerjaan rumah.
Bruce
Saya mencoba untuk memetakan grafik distribusi derajat jaringan.
Bruce
5
@ Peter: Harap perbarui pertanyaan Anda dengan informasi yang bermanfaat. Tolong jangan menambahkan komentar ke pertanyaan Anda - Anda memiliki pertanyaan, Anda dapat memperbaikinya menjadi lengkap dan jelas.
S.Lott
Jawaban:
147
Catatan: Anda harus mengurutkan daftar sebelum menggunakan groupby.
Anda dapat menggunakan groupbydari itertoolspaket jika daftar adalah daftar yang diurutkan.
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]from itertools import groupby[len(list(group))for key, group in groupby(a)]
bagus, menggunakan groupby. Saya bertanya-tanya tentang efisiensinya versus pendekatan dikt,
Eli Bendersky
32
Python groupby membuat grup baru ketika nilai yang dilihatnya berubah. Dalam hal ini 1,1,1,2,1,1,1] akan kembali [3,1,3]. Jika Anda berharap [6,1] maka pastikan untuk mengurutkan data sebelum menggunakan groupby.
Evan
4
@CristianCiupitu: sum(1 for _ in group).
Martijn Pieters
6
Ini bukan solusi. Keluaran tidak memberi tahu apa yang dihitung.
buhtz
8
[(key, len(list(group))) for key, group in groupby(a)]atau {key: len(list(group)) for key, group in groupby(a)}@buhtz
Eric Pauley
532
Di Python 2.7 (atau lebih baru), Anda dapat menggunakan collections.Counter:
@unutbu: Bagaimana jika saya memiliki tiga daftar, a, b, c yang a dan b tetap sama, tetapi c berubah? Bagaimana cara menghitung nilai c dimana a dan c sama?
ThePredator
@Srivatsan: Saya tidak mengerti situasinya. Silakan kirim pertanyaan baru di mana Anda dapat menguraikan.
unutbu
1
Apakah ada cara untuk mengekstrak kamus {1: 4, 2: 4, 3: 2, 5: 2, 4: 1} dari objek counter?
Pavan
7
@Pavan: collections.Counteradalah subkelas dari dict. Anda dapat menggunakannya dengan cara yang sama seperti yang Anda lakukan pada dict normal. Namun, jika Anda benar-benar menginginkan dikt, Anda dapat mengonversinya menjadi dikt menggunakan dict(counter).
unutbu
1
Berfungsi di 3.6 juga, jadi anggap sesuatu yang lebih besar dari 2,7
kpierce8
108
Python 2.7+ memperkenalkan Kamus Pemahaman. Membangun kamus dari daftar akan membuat Anda menghitung serta menyingkirkan duplikat.
>>> a =[1,1,1,1,2,2,2,2,3,3,4,5,5]>>> d ={x:a.count(x)for x in a}>>> d
{1:4,2:4,3:2,4:1,5:2}>>> a, b = d.keys(), d.values()>>> a
[1,2,3,4,5]>>> b
[4,4,2,1,2]
Ini bekerja sangat baik dengan daftar string yang bertentangan dengan bilangan bulat seperti pertanyaan awal yang diajukan.
Glen Selle
15
Lebih cepat menggunakan satu set:{x:a.count(x) for x in set(a)}
stenci
45
Ini sangat tidak efisien . a.count()melakukan lintasan penuh untuk setiap elemen dalam a, menjadikan ini pendekatan O (N ^ 2) kuadratik. collections.Counter()adalah jauh lebih efisien karena penting dalam waktu linear (O (N)). Dalam angka, itu berarti pendekatan ini akan mengeksekusi 1 juta langkah untuk daftar panjang 1000, vs hanya 1000 langkah dengan Counter(), 10 ^ 12 langkah di mana hanya 10 ^ 6 dibutuhkan oleh Counter untuk sejuta item dalam daftar, dll.
Martijn Pieters
3
@stenci: tentu, tetapi kengerian menggunakan a.count()sepenuhnya kerdil efisiensi menggunakan set di sana.
Martijn Pieters
2
@ MartijnPieters satu lagi alasan untuk menggunakannya lebih sedikit kali :)
stenci
48
Untuk menghitung jumlah penampilan:
from collections import defaultdict
appearances = defaultdict(int)for curr in a:
appearances[curr]+=1
@phkahler: Milik saya hanya akan sedikit lebih baik dari ini. Sangat tidak layak saya memposting jawaban terpisah ketika ini dapat ditingkatkan dengan perubahan kecil. Tujuan SO adalah untuk mendapatkan jawaban terbaik . Saya cukup mengedit ini, tetapi saya lebih suka membiarkan penulis asli kesempatan untuk melakukan perbaikan sendiri.
S.Lott
1
@ S.Lott Kode jauh lebih bersih tanpa harus mengimpor defaultdict.
bstrauch24
Mengapa tidak preinitialize b: b = {k:0 for k in a}?
DylanYoung
20
Berikut ini adalah alternatif penggunaan succint lain itertools.groupbyyang juga berfungsi untuk input yang tidak terurut:
from itertools import groupby
items =[5,1,1,2,2,1,1,2,2,3,4,3,5]
results ={value: len(list(freq))for value, freq in groupby(sorted(items))}
Sementara cuplikan kode ini mungkin solusinya, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda
Rahul Gupta
Ya akan melakukannya Rahul Gupta
Anirban Lahiri
7
seta = set(a)
b =[a.count(el)for el in seta]
a = list(seta)#Only if you really want it.
menggunakan daftar countsangat mahal dan tidak pantas untuk skenario ini.
Idan K
@IdanK mengapa menghitung itu mahal?
Kritika Rajain
@KritikaRajain Untuk setiap elemen unik dalam daftar, Anda mengulangi seluruh daftar untuk menghasilkan hitungan (kuadratik dalam jumlah elemen unik dalam daftar). Sebagai gantinya, Anda dapat mengulangi daftar sekali dan menghitung jumlah setiap elemen unik (linier dalam ukuran daftar). Jika daftar Anda hanya memiliki satu elemen unik, hasilnya akan sama. Selain itu, pendekatan ini membutuhkan set perantara tambahan.
DylanYoung
7
Saya hanya akan menggunakan scipy.stats.itemfreq dengan cara berikut:
from scipy.stats import itemfreq
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]
freq = itemfreq(a)
a = freq[:,0]
b = freq[:,1]
a =[1,1,1,1,2,2,2,2,3,3,3,4,4]
d ={}for item in a:if item in d:
d[item]= d.get(item)+1else:
d[item]=1for k,v in d.items():print(str(k)+':'+str(v))# output#1:4#2:4#3:3#4:2#remove dups
d = set(a)print(d)#{1, 2, 3, 4}
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]# 1. Get counts and store in another list
output =[]for i in set(a):
output.append(a.count(i))print(output)# 2. Remove duplicates using set constructor
a = list(set(a))print(a)
Kumpulan koleksi tidak memungkinkan duplikat, meneruskan daftar ke konstruktor set () akan memberikan objek yang benar-benar unik. fungsi count () mengembalikan jumlah integer ketika objek yang ada dalam daftar diteruskan. Dengan itu objek unik dihitung dan masing-masing nilai hitungan disimpan dengan menambahkan ke output daftar kosong
list () konstruktor digunakan untuk mengonversi set (a) menjadi daftar dan dirujuk oleh variabel yang sama a
def frequency(l):
d ={}for i in l:if i in d.keys():
d[i]+=1else:
d[i]=1for k, v in d.iteritems():if v ==max (d.values()):return k,d.keys()print(frequency([10,10,10,10,20,20,20,20,40,40,50,50,30]))
max(d.values())tidak akan berubah di loop terakhir. Jangan hitung dalam loop, hitung sebelum loop.
DylanYoung
1
#!usr/bin/pythondef frq(words):
freq ={}for w in words:if w in freq:
freq[w]= freq.get(w)+1else:
freq[w]=1return freq
fp = open("poem","r")
list = fp.read()
fp.close()
input = list.split()print input
d = frq(input)print"frequency of input\n: "print d
fp1 = open("output.txt","w+")for k,v in d.items():
fp1.write(str(k)+':'+str(v)+"\n")
fp1.close()
num=[3,2,3,5,5,3,7,6,4,6,7,2]print('\nelements are:\t',num)
count_dict={}for elements in num:
count_dict[elements]=num.count(elements)print('\nfrequency:\t',count_dict)
Tolong jangan memposting jawaban hanya kode tetapi mengklarifikasi kode Anda, terutama ketika pertanyaan sudah memiliki jawaban yang valid.
Erik A
1
from collections importOrderedDict
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]def get_count(lists):
dictionary =OrderedDict()for val in lists:
dictionary.setdefault(val,[]).append(1)return[sum(val)for val in dictionary.values()]print(get_count(a))>>>[4,4,2,1,2]
Saya menggunakan Penghitung untuk menghasilkan freq. dikt dari kata-kata file teks dalam 1 baris kode
def _fileIndex(fh):''' create a dict using Counter of a
flat list of words (re.findall(re.compile(r"[a-zA-Z]+"), lines)) in (lines in file->for lines in fh)
'''returnCounter([wrd.lower()for wrdList in[words for words in[re.findall(re.compile(r'[a-zA-Z]+'), lines)for lines in fh]]for wrd in wrdList])
Solusi lain dengan algoritma lain tanpa menggunakan koleksi:
def countFreq(A):
n=len(A)
count=[0]*n # Create a new list initialized with '0'for i in range(n):
count[A[i]]+=1# increase occurrence for value A[i]return[x for x in count if x]# return non-zero count
>>> L =[1,1,1,1,2,2,2,2,3,3,4,5,5]>>>import functools
>>>>>> functools.reduce(lambda acc, e:[v+(i==e)for i, v in enumerate(acc,1)]if e<=len(acc)else acc+[0for _ in range(e-len(acc)-1)]+[1], L,[])[4,4,2,1,2]
Lebih bersih jika Anda menghitung nol juga:
>>> functools.reduce(lambda acc, e:[v+(i==e)for i, v in enumerate(acc)]if e<len(acc)else acc+[0for _ in range(e-len(acc))]+[1], L,[])[0,4,4,2,1,2]
Sebuah penjelasan:
kita mulai dengan accdaftar kosong ;
jika elemen berikutnya edari Llebih rendah dari ukuran acc, kami hanya update elemen ini: v+(i==e)berarti v+1jika indeks idari accadalah elemen saat ini e, jika nilai sebelumnya v;
jika elemen berikutnya edari Llebih besar atau sama dengan ukuran acc, kami harus memperluas accuntuk menjadi tuan rumah baru 1.
Elemen tidak harus diurutkan ( itertools.groupby). Anda akan mendapatkan hasil yang aneh jika Anda memiliki angka negatif.
Menemukan cara lain untuk melakukan ini, menggunakan set.
#ar is the list of elements#convert ar to set to get unique elements
sock_set = set(ar)#create dictionary of frequency of socks
sock_dict ={}for sock in sock_set:
sock_dict[sock]= ar.count(sock)
Untuk menemukan jumlah elemen unik dalam array yang diurutkan menggunakan kamus
defCountFrequency(my_list):# Creating an empty dictionary
freq ={}for item in my_list:if(item in freq):
freq[item]+=1else:
freq[item]=1for key, value in freq.items():print("% d : % d"%(key, value))# Driver function if __name__ =="__main__":
my_list =[1,1,1,5,5,3,1,3,3,1,4,4,4,2,2,2,2]CountFrequency(my_list)
Satu lagi cara adalah dengan menggunakan kamus dan list.count, di bawah ini cara naif untuk melakukannya.
dicio = dict()
a =[1,1,1,1,2,2,2,2,3,3,4,5,5]
b = list()
c = list()for i in a:if i in dicio:continueelse:
dicio[i]= a.count(i)
b.append(a.count(i))
c.append(i)print(b)print(c)
Jawaban:
Catatan: Anda harus mengurutkan daftar sebelum menggunakan
groupby
.Anda dapat menggunakan
groupby
dariitertools
paket jika daftar adalah daftar yang diurutkan.Keluaran:
sumber
groupby
. Saya bertanya-tanya tentang efisiensinya versus pendekatan dikt,sum(1 for _ in group)
.[(key, len(list(group))) for key, group in groupby(a)]
atau{key: len(list(group)) for key, group in groupby(a)}
@buhtzDi Python 2.7 (atau lebih baru), Anda dapat menggunakan
collections.Counter
:Jika Anda menggunakan Python 2.6 atau yang lebih lama, Anda dapat mengunduhnya di sini .
sumber
collections.Counter
adalah subkelas daridict
. Anda dapat menggunakannya dengan cara yang sama seperti yang Anda lakukan pada dict normal. Namun, jika Anda benar-benar menginginkan dikt, Anda dapat mengonversinya menjadi dikt menggunakandict(counter)
.Python 2.7+ memperkenalkan Kamus Pemahaman. Membangun kamus dari daftar akan membuat Anda menghitung serta menyingkirkan duplikat.
sumber
{x:a.count(x) for x in set(a)}
a.count()
melakukan lintasan penuh untuk setiap elemen dalama
, menjadikan ini pendekatan O (N ^ 2) kuadratik.collections.Counter()
adalah jauh lebih efisien karena penting dalam waktu linear (O (N)). Dalam angka, itu berarti pendekatan ini akan mengeksekusi 1 juta langkah untuk daftar panjang 1000, vs hanya 1000 langkah denganCounter()
, 10 ^ 12 langkah di mana hanya 10 ^ 6 dibutuhkan oleh Counter untuk sejuta item dalam daftar, dll.a.count()
sepenuhnya kerdil efisiensi menggunakan set di sana.Untuk menghitung jumlah penampilan:
Untuk menghapus duplikat:
sumber
Counter
bisa menggunakan beberapa tipe numerik termasukfloat
atauDecimal
, bukan hanyaint
.Dalam Python 2.7+, Anda bisa menggunakan collections.Counter untuk menghitung item
sumber
Menghitung frekuensi elemen mungkin paling baik dilakukan dengan kamus:
Untuk menghapus duplikat, gunakan satu set:
sumber
defaultdict
.b = {k:0 for k in a}
?Berikut ini adalah alternatif penggunaan succint lain
itertools.groupby
yang juga berfungsi untuk input yang tidak terurut:hasil
sumber
Kamu bisa melakukan ini:
Keluaran:
Array pertama adalah nilai, dan array kedua adalah jumlah elemen dengan nilai-nilai ini.
Jadi Jika Anda ingin mendapatkan hanya array dengan angka, Anda harus menggunakan ini:
sumber
sumber
sumber
count
sangat mahal dan tidak pantas untuk skenario ini.Saya hanya akan menggunakan scipy.stats.itemfreq dengan cara berikut:
Anda dapat memeriksa dokumentasinya di sini: http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.itemfreq.html
sumber
Untuk pertanyaan pertama Anda, ulangi daftar dan gunakan kamus untuk melacak keberadaan elemen.
Untuk pertanyaan kedua Anda, cukup gunakan operator yang telah ditentukan.
sumber
Jawaban ini lebih eksplisit
sumber
...
sumber
Saya agak terlambat, tetapi ini juga akan berhasil, dan akan membantu orang lain:
akan menghasilkan ini ..
sumber
Keluaran
sumber
Solusi sederhana menggunakan kamus.
sumber
max(d.values())
tidak akan berubah di loop terakhir. Jangan hitung dalam loop, hitung sebelum loop.sumber
sumber
Untuk menghapus duplikat dan Menjaga pesanan:
sumber
Saya menggunakan Penghitung untuk menghasilkan freq. dikt dari kata-kata file teks dalam 1 baris kode
sumber
Pendekatan lain untuk melakukan ini, meskipun dengan menggunakan perpustakaan yang lebih berat tetapi kuat - NLTK.
sumber
Solusi lain dengan algoritma lain tanpa menggunakan koleksi:
sumber
Anda dapat menggunakan fungsi built-in yang disediakan dengan python
Kode di atas secara otomatis menghapus duplikat dalam daftar dan juga mencetak frekuensi setiap elemen dalam daftar asli dan daftar tanpa duplikat.
Dua burung untuk satu tembakan! XD
sumber
Pendekatan ini dapat dicoba jika Anda tidak ingin menggunakan perpustakaan apa pun dan tetap sederhana dan singkat!
o / h
sumber
Sebagai catatan, jawaban fungsional:
Lebih bersih jika Anda menghitung nol juga:
Sebuah penjelasan:
acc
daftar kosong ;e
dariL
lebih rendah dari ukuranacc
, kami hanya update elemen ini:v+(i==e)
berartiv+1
jika indeksi
dariacc
adalah elemen saat inie
, jika nilai sebelumnyav
;e
dariL
lebih besar atau sama dengan ukuranacc
, kami harus memperluasacc
untuk menjadi tuan rumah baru1
.Elemen tidak harus diurutkan (
itertools.groupby
). Anda akan mendapatkan hasil yang aneh jika Anda memiliki angka negatif.sumber
Menemukan cara lain untuk melakukan ini, menggunakan set.
sumber
sumber
Satu lagi cara adalah dengan menggunakan kamus dan list.count, di bawah ini cara naif untuk melakukannya.
sumber
sumber