ใน Python สามารถหาจำนวนขององค์ประกอบทั้งหมดในรายการหรือทูเพิลได้โดยใช้ฟังก์ชันในตัว len() และจำนวนของแต่ละองค์ประกอบ (จำนวนการเกิดขึ้นของแต่ละองค์ประกอบ) สามารถรับได้โดยใช้เมธอด count() .
นอกจากนี้ คลาส Counter ของคอลเล็กชันไลบรารีมาตรฐาน Python สามารถใช้เพื่อรับองค์ประกอบตามลำดับจำนวนครั้งที่เกิดขึ้น
ในส่วนนี้เราจะพูดถึงสิ่งต่อไปนี้
- นับจำนวนองค์ประกอบทั้งหมด:
len()
- นับจำนวนองค์ประกอบแต่ละองค์ประกอบ (จำนวนครั้งของแต่ละองค์ประกอบ):
count()
- การใช้งาน
collections.Counter
- องค์ประกอบถูกดึงมาตามลำดับความถี่ของการเกิด:
most_common()
- นับจำนวน (ประเภท) ขององค์ประกอบที่ไม่ทับซ้อนกัน (องค์ประกอบที่ไม่ซ้ำ)
- นับจำนวนองค์ประกอบที่ตรงตามเงื่อนไข
นอกจากนี้ เป็นตัวอย่างที่เป็นรูปธรรม ต่อไปนี้จะอธิบายด้วยโค้ดตัวอย่าง
- นับจำนวนครั้งของคำในสตริง
- นับจำนวนการเกิดขึ้นของอักขระในสตริง
ตัวอย่างเป็นรายการ แต่การประมวลผลแบบเดียวกันสามารถทำได้ด้วยสิ่งอันดับ
- นับจำนวนองค์ประกอบทั้งหมด: len()
- การนับจำนวนองค์ประกอบแต่ละองค์ประกอบ (จำนวนครั้งของแต่ละองค์ประกอบ): count() method
- วิธีใช้ collections.Counter
- การรับองค์ประกอบตามลำดับความถี่ของลักษณะที่ปรากฏ: most_common() method
- นับจำนวน (ประเภท) ขององค์ประกอบที่ไม่ทับซ้อนกัน (องค์ประกอบที่ไม่ซ้ำ)
- นับจำนวนองค์ประกอบที่ตรงตามเงื่อนไข
- นับจำนวนครั้งของคำในสตริง
- นับจำนวนการเกิดขึ้นของอักขระในสตริง
นับจำนวนองค์ประกอบทั้งหมด: len()
ในการนับจำนวนองค์ประกอบทั้งหมดในรายการหรือทูเพิล ให้ใช้ฟังก์ชัน len() ในตัว
l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
print(len(l))
# 7
การนับจำนวนองค์ประกอบแต่ละองค์ประกอบ (จำนวนครั้งของแต่ละองค์ประกอบ): count() method
ในการนับจำนวนของแต่ละองค์ประกอบ (จำนวนครั้งที่เกิดขึ้นของแต่ละองค์ประกอบ) ให้ใช้วิธี count() สำหรับรายการ สิ่งอันดับ ฯลฯ
หากค่าที่ไม่มีอยู่ในองค์ประกอบถูกส่งเป็นอาร์กิวเมนต์ ระบบจะส่งคืน 0
l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
print(l.count('a'))
# 4
print(l.count('b'))
# 1
print(l.count('c'))
# 2
print(l.count('d'))
# 0
หากคุณต้องการรับจำนวนครั้งของแต่ละองค์ประกอบในคราวเดียว คอลเล็กชันต่อไปนี้ ตัวนับมีประโยชน์
วิธีใช้ collections.Counter
คอลเล็กชันไลบรารีมาตรฐานของ Python มีคลาส Counter
Counter() เป็นคลาสย่อยของ dict ประเภทพจนานุกรม ซึ่งมีข้อมูลในรูปแบบขององค์ประกอบเป็นคีย์และเกิดขึ้นเป็นค่า
import collections
l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)
print(c)
# Counter({'a': 4, 'c': 2, 'b': 1})
print(type(c))
# <class 'collections.Counter'>
print(issubclass(type(c), dict))
# True
หากระบุองค์ประกอบเป็นคีย์ สามารถรับจำนวนองค์ประกอบได้ หากมีการระบุค่าที่ไม่มีอยู่ในองค์ประกอบ ระบบจะส่งคืน 0
print(c['a'])
# 4
print(c['b'])
# 1
print(c['c'])
# 2
print(c['d'])
# 0
คุณยังสามารถใช้วิธีประเภทพจนานุกรม เช่น คีย์ (), ค่า (), รายการ () เป็นต้น
print(c.keys())
# dict_keys(['a', 'b', 'c'])
print(c.values())
# dict_values([4, 1, 2])
print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])
เมธอดเหล่านี้ส่งคืนอ็อบเจ็กต์ประเภท dict_keys เป็นต้น ซึ่งสามารถใช้ได้เหมือนกับที่คุณต้องการเรียกใช้คำสั่ง for หากคุณต้องการแปลงเป็นรายการ ให้ใช้ list()
การรับองค์ประกอบตามลำดับความถี่ของลักษณะที่ปรากฏ: most_common() method
ตัวนับมีเมธอด most_common() ซึ่งส่งคืนรายการทูเพิลของแบบฟอร์ม (องค์ประกอบ จำนวนครั้ง) ที่จัดเรียงตามจำนวนครั้งที่เกิดขึ้น
print(c.most_common())
# [('a', 4), ('c', 2), ('b', 1)]
องค์ประกอบที่มีจำนวนครั้งสูงสุดสามารถรับได้โดยการระบุดัชนี เช่น [0] สำหรับจำนวนครั้งสูงสุดและ [-1] สำหรับจำนวนครั้งน้อยที่สุด หากคุณต้องการรับเฉพาะองค์ประกอบหรือจำนวนครั้งเท่านั้น คุณสามารถระบุดัชนีเพิ่มเติมได้
print(c.most_common()[0])
# ('a', 4)
print(c.most_common()[-1])
# ('b', 1)
print(c.most_common()[0][0])
# a
print(c.most_common()[0][1])
# 4
หากคุณต้องการเรียงลำดับตามจำนวนครั้งที่เกิดลดลง ให้ใช้สไลซ์โดยตั้งค่าส่วนเพิ่มเป็น -1
print(c.most_common()[::-1])
# [('b', 1), ('c', 2), ('a', 4)]
หากระบุอาร์กิวเมนต์ n สำหรับเมธอด most_common() จะส่งคืนเฉพาะองค์ประกอบ n รายการที่มีจำนวนครั้งสูงสุดเท่านั้น หากละเว้นองค์ประกอบทั้งหมด
print(c.most_common(2))
# [('a', 4), ('c', 2)]
หากคุณต้องการแยกรายการองค์ประกอบ/รายการโดยเรียงลำดับตามจำนวนการเกิดขึ้น แทนที่จะเป็นทูเพิล (องค์ประกอบ จำนวนรายการ) คุณสามารถแยกย่อยได้ดังนี้
values, counts = zip(*c.most_common())
print(values)
# ('a', 'c', 'b')
print(counts)
# (4, 2, 1)
ฟังก์ชันในตัว zip() ใช้เพื่อย้ายรายการสองมิติ (ในกรณีนี้คือรายการทูเพิล) จากนั้นแกะและแตกไฟล์
นับจำนวน (ประเภท) ขององค์ประกอบที่ไม่ทับซ้อนกัน (องค์ประกอบที่ไม่ซ้ำ)
ในการนับจำนวนองค์ประกอบที่ไม่ทับซ้อนกัน (องค์ประกอบที่ไม่ซ้ำ) ที่มีอยู่ในรายการหรือทูเพิล (มีกี่ประเภท) ให้ใช้ตัวนับหรือ set() ตามที่อธิบายไว้ข้างต้น
จำนวนองค์ประกอบในวัตถุ Counter เท่ากับจำนวนขององค์ประกอบที่ไม่ทับซ้อนกันในรายการดั้งเดิม ซึ่งสามารถรับได้ด้วย len()
l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)
print(len(c))
# 3
คุณยังสามารถใช้ set() ตัวสร้างสำหรับชุดประเภทชุด ซึ่งจะง่ายกว่าถ้าคุณไม่ต้องการวัตถุตัวนับ
ประเภทชุดเป็นประเภทข้อมูลที่ไม่มีองค์ประกอบที่ซ้ำกัน การส่งรายการไปที่ set() จะละเว้นค่าที่ซ้ำกันและส่งคืนอ็อบเจ็กต์ประเภท set โดยมีค่าเฉพาะเป็นองค์ประกอบ จำนวนขององค์ประกอบประเภทนี้ได้มาจาก len()
print(set(l))
# {'a', 'c', 'b'}
print(len(set(l)))
# 3
นับจำนวนองค์ประกอบที่ตรงตามเงื่อนไข
ในการนับจำนวนองค์ประกอบในรายการหรือทูเพิลที่ตรงตามเงื่อนไขที่กำหนด ให้ใช้สัญลักษณ์ความเข้าใจรายการหรือนิพจน์ตัวสร้าง
ตัวอย่างเช่น นับจำนวนองค์ประกอบที่มีค่าลบสำหรับรายการตัวเลขต่อไปนี้
l = list(range(-5, 6))
print(l)
# [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
การใช้นิพจน์เงื่อนไขกับแต่ละองค์ประกอบในสัญลักษณ์ความเข้าใจแบบรายการจะทำให้ได้รายการที่มีองค์ประกอบเป็นบูลีนบูล (จริง เท็จ) บูลประเภทบูลีนเป็นคลาสย่อยของ int ชนิดจำนวนเต็ม โดยที่ true ถือเป็น 1 และเท็จเป็น 0 ดังนั้น จำนวนค่าจริง (จำนวนองค์ประกอบที่ตรงตามเงื่อนไข) สามารถนับได้โดยการคำนวณผลรวมโดยใช้ผลรวม ().
print([i < 0 for i in l])
# [True, True, True, True, True, False, False, False, False, False, False]
print(sum([i < 0 for i in l]))
# 5
หากเราแทนที่ [] ในสัญกรณ์ความเข้าใจรายการด้วย () เราจะได้รับนิพจน์ตัวสร้าง สัญกรณ์ความเข้าใจรายการจะสร้างรายการขององค์ประกอบทั้งหมดที่ประมวลผล ในขณะที่นิพจน์ของตัวสร้างจะประมวลผลองค์ประกอบตามลำดับ ดังนั้นจึงมีประสิทธิภาพในหน่วยความจำมากกว่า
เมื่อนิพจน์ตัวสร้างเป็นอาร์กิวเมนต์เดียว () สามารถละเว้นได้ จึงสามารถเขียนได้ในกรณีหลัง
print(sum((i < 0 for i in l)))
# 5
print(sum(i < 0 for i in l))
# 5
หากคุณต้องการนับจำนวนค่าเท็จ (จำนวนองค์ประกอบที่ไม่เป็นไปตามเงื่อนไข) ให้ใช้อย่า โปรดทราบว่า > มีลำดับความสำคัญที่สูงกว่า (คำนวณก่อน) ดังนั้นวงเล็บ () ใน (i < 0) ในตัวอย่างต่อไปนี้จึงไม่จำเป็น
print([not (i < 0) for i in l])
# [False, False, False, False, False, True, True, True, True, True, True]
print(sum(not (i < 0) for i in l))
# 6
แน่นอนเงื่อนไขสามารถเปลี่ยนแปลงได้
print(sum(i >= 0 for i in l))
# 6
ตัวอย่างอื่น ๆ แสดงไว้ด้านล่าง
ตัวอย่างการรับจำนวนองค์ประกอบคี่สำหรับรายการตัวเลข
print([i % 2 == 1 for i in l])
# [True, False, True, False, True, False, True, False, True, False, True]
print(sum(i % 2 == 1 for i in l))
# 6
ตัวอย่างเงื่อนไขสำหรับรายการสตริง
l = ['apple', 'orange', 'banana']
print([s.endswith('e') for s in l])
# [True, True, False]
print(sum(s.endswith('e') for s in l))
# 2
ตัวนับใช้เพื่อนับตามจำนวนครั้งที่เกิดขึ้น items() ดึง tuple ของ (องค์ประกอบ, จำนวนครั้ง) และจำนวนครั้งที่เกิดขึ้นจะระบุเงื่อนไข
ต่อไปนี้คือตัวอย่างการแยกองค์ประกอบที่มีสองรายการขึ้นไปและนับจำนวนครั้งทั้งหมด ในตัวอย่างนี้ มีสี่ตัวและสอง c รวมเป็นหก
l = ['a', 'a', 'a', 'a', 'b', 'c', 'c']
c = collections.Counter(l)
print(c.items())
# dict_items([('a', 4), ('b', 1), ('c', 2)])
print([i for i in l if c[i] >= 2])
# ['a', 'a', 'a', 'a', 'c', 'c']
print([i[1] for i in c.items() if i[1] >= 2])
# [4, 2]
print(sum(i[1] for i in c.items() if i[1] >= 2))
# 6
ต่อไปนี้เป็นตัวอย่างการแยกประเภทขององค์ประกอบที่มีสองรายการขึ้นไปและนับจำนวนครั้งที่เกิดขึ้น ในตัวอย่างนี้ มีสองประเภทคือ a และ c
print([i[0] for i in c.items() if i[1] >= 2])
# ['a', 'c']
print([i[1] >= 2 for i in c.items()])
# [True, False, True]
print(sum(i[1] >= 2 for i in c.items()))
# 2
นับจำนวนครั้งของคำในสตริง
เป็นตัวอย่างที่ชัดเจน ลองนับจำนวนครั้งของคำในสตริง
ขั้นแรก แทนที่เครื่องหมายจุลภาคและมหัพภาคที่ไม่จำเป็นด้วยสตริงว่างโดยใช้เมธอด replace() แล้วลบทิ้ง จากนั้น ใช้เมธอด split() เพื่อสร้างรายการโดยคั่นด้วยช่องว่าง
s = 'government of the people, by the people, for the people.'
s_remove = s.replace(',', '').replace('.', '')
print(s_remove)
# government of the people by the people for the people
word_list = s_remove.split()
print(word_list)
# ['government', 'of', 'the', 'people', 'by', 'the', 'people', 'for', 'the', 'people']
หากคุณสร้างรายการได้ คุณจะได้รับจำนวนครั้งที่แต่ละคำปรากฏขึ้น ประเภทของคำที่ปรากฏ และ most_common() ของ collections.Counter เพื่อให้ได้คำที่ปรากฏบ่อยที่สุด
print(word_list.count('people'))
# 3
print(len(set(word_list)))
# 6
c = collections.Counter(word_list)
print(c)
# Counter({'the': 3, 'people': 3, 'government': 1, 'of': 1, 'by': 1, 'for': 1})
print(c.most_common()[0][0])
# the
ข้างต้นเป็นกระบวนการที่ง่ายมาก ดังนั้นควรใช้ไลบรารีเช่น NLTK สำหรับการประมวลผลภาษาธรรมชาติที่ซับซ้อนมากขึ้น
นอกจากนี้ ในกรณีของข้อความภาษาญี่ปุ่น ไม่สามารถใช้ split() เพื่อแยกข้อความได้เนื่องจากไม่มีการแยกคำที่ชัดเจน ตัวอย่างเช่น คุณสามารถใช้ไลบรารี Janome เพื่อทำสิ่งนี้ให้สำเร็จ
นับจำนวนการเกิดขึ้นของอักขระในสตริง
เนื่องจากสตริงเป็นประเภทลำดับด้วย จึงสามารถใช้กับเมธอด count() หรือส่งผ่านเป็นอาร์กิวเมนต์ไปยังตัวสร้างของ collections.Counter()
s = 'supercalifragilisticexpialidocious'
print(s.count('p'))
# 2
c = collections.Counter(s)
print(c)
# Counter({'i': 7, 's': 3, 'c': 3, 'a': 3, 'l': 3, 'u': 2, 'p': 2, 'e': 2, 'r': 2, 'o': 2, 'f': 1, 'g': 1, 't': 1, 'x': 1, 'd': 1})
ตัวอย่างการดึงอักขระ 5 อันดับแรกที่เกิดขึ้นบ่อยที่สุด
print(c.most_common(5))
# [('i', 7), ('s', 3), ('c', 3), ('a', 3), ('l', 3)]
values, counts = zip(*c.most_common(5))
print(values)
# ('i', 's', 'c', 'a', 'l')