Contar el número de ocurrencias de palabras en List Python

En este tutorial, aprenderemos a contar la cantidad de veces que aparece una palabra en una lista en Python usando Pandas/Numpy, la función count(), un bucle for y la función Counter() del módulo de colecciones y el punto de referencia. a ellos.

Introducción

Contar la frecuencia de palabras en un elemento de lista en Python es una tarea relativamente común, especialmente cuando se crean datos de distribución para histogramas.

Digamos que tenemos una lista ['b', 'b', 'a'] - tenemos dos ocurrencias en "b" y una en "a". Esta guía le mostrará tres formas diferentes de contar el número de ocurrencias de palabras en una lista de Python:

  • Usando Pandas y Numpy
  • Usando la función contar()
  • Usando el Contador del Módulo de Colección
  • Uso de un bucle y una variable de contador

En la práctica, usará Pandas/Nunpy, la función count() o Counter, ya que son muy convenientes de usar.

Uso de Pandas y Numpy

La forma más corta y fácil de obtener recuentos de valores en un formato fácilmente manipulable (DataFrame) es a través de Numpy y Pandas. Podemos envolver la lista en una matriz Numpy y luego llamar al método value_counts() de la instancia pd (que también está disponible para todas las instancias DataFrame):

1
2
3
4
5
6
import numpy as np
import pandas as pd

words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']

pd.value_counts(np.array(words))

Esto da como resultado un DataFrame que contiene:

1
2
3
4
5
6
hello      3
goodbye    1
bye        1
howdy      1
hi         1
dtype: int64

Puede acceder a su campo values para obtener los recuentos, o index para obtener las palabras:

1
2
3
4
df = pd.value_counts(np.array(words))

print('Index:', df.index)
print('Values:', df.values)

Esto resulta en:

1
2
3
Index: Index(['hello', 'goodbye', 'bye', 'howdy', 'hi'], dtype='object')

Values: [3 1 1 1 1]

Usar la función contar()

La forma "estándar" (sin bibliotecas externas) de obtener el recuento de ocurrencias de palabras en una lista es mediante el uso de la función count() del objeto de lista.

El método count() es una función integrada que toma un elemento como su único argumento y devuelve el número de veces que ese elemento aparece en la lista.

La complejidad de la función count() es O(n), donde n es el número de factores presentes en la lista.

El siguiente código usa count() para obtener el número de ocurrencias de una palabra en una lista:

1
2
3
4
words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']

print(f'"hello" appears {words.count("hello")} time(s)')
print(f'"howdy" appears {words.count("howdy")} time(s)')

Esto debería darnos el mismo resultado que antes de usar bucles:

1
2
"hello" appears 3 time(s)
"howdy" appears 1 time(s)

El método count() nos ofrece una manera fácil de obtener el número de ocurrencias de palabras en una lista para cada palabra individual.

Usando el Contador del módulo de colección

La instancia de la clase Contador se puede usar para contar instancias de otros objetos. Al pasar una lista a su constructor, instanciamos un Contador que devuelve un diccionario de todos los elementos y sus ocurrencias en una lista.

A partir de ahí, para obtener la ocurrencia de una sola palabra, puede usar la palabra como clave para el diccionario:

1
2
3
4
5
6
7
8
from collections import Counter

words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']

word_counts = Counter(words)

print(f'"hello" appears {word_counts["hello"]} time(s)')
print(f'"howdy" appears {word_counts["howdy"]} time(s)')

Esto resulta en:

1
2
"hello" appears 3 time(s)
"howdy" appears 1 time(s)

Uso de un bucle y una variable de contador

En última instancia, funcionará un enfoque de fuerza bruta que recorre cada palabra de la lista, incrementando un contador en uno cuando se encuentra la palabra y devolviendo el recuento total de palabras.

Por supuesto, este método se vuelve más ineficiente a medida que crece el tamaño de la lista, simplemente es conceptualmente fácil de entender e implementar.

El siguiente código usa este enfoque en el método count_occurrence():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def count_occurrence(words, word_to_count):
    count = 0
    for word in words:
        if word == word_to_count:
          # update counter variable
            count = count + 1
    return count


words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']
print(f'"hello" appears {count_occurrence(words, "hello")} time(s)')
print(f'"howdy" appears {count_occurrence(words, "howdy")} time(s)')

Si ejecuta este código, debería ver este resultado:

1
2
"hello" appears 3 time(s)
"howdy" appears 1 time(s)

¡Bonito y fácil!

¿La solución más eficiente? {#la solución más eficiente}

Naturalmente, buscará la solución más eficiente si se trata de un gran corpus de palabras. Hagamos una evaluación comparativa de todos estos para ver cómo funcionan.

La tarea se puede dividir en la búsqueda de ocurrencias para todas las palabras o una sola palabra, y haremos puntos de referencia para ambas, comenzando con todas las palabras:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np
import pandas as pd
import collections

def pdNumpy(words):
    def _pdNumpy():
        return pd.value_counts(np.array(words))
    return _pdNumpy

def countFunction(words):
    def _countFunction():
        counts = []
        for word in words:
            counts.append(words.count(word))
        return counts
    return _countFunction

def counterObject(words):
    def _counterObject():
        return collections.Counter(words)
    return _counterObject
    
import timeit

words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']

print("Time to execute:\n")
print("Pandas/Numpy: %ss" % timeit.Timer(pdNumpy(words)).timeit(1000))
print("count(): %ss" % timeit.Timer(countFunction(words)).timeit(1000))
print("Counter: %ss" % timeit.Timer(counterObject(words)).timeit(1000))

Lo que resulta en:

1
2
3
4
5
Time to execute:

Pandas/Numpy: 0.33886080000047514s
count(): 0.0009540999999444466s
Counter: 0.0019409999995332328s

El método count() es extremadamente rápido en comparación con las otras variantes, sin embargo, no nos da las etiquetas asociadas con los conteos como lo hacen los otros dos.

Si necesita las etiquetas, el “Contador” supera el proceso ineficiente de envolver la lista en una matriz Numpy y luego contar.

Por otro lado, puede hacer uso de los métodos de DataFrame para ordenar u otra manipulación que no puede hacer de otra manera. Contador también tiene algunos métodos únicos.

En última instancia, puede usar el Contador para crear un diccionario y convertir el diccionario en un DataFrame también, para aprovechar la velocidad del Contador y la versatilidad de DataFrames:

1
df = pd.DataFrame.from_dict([Counter(words)]).T

Si no necesita las etiquetas, count() es el camino a seguir.

Alternativamente, si está buscando una sola palabra:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import numpy as np
import pandas as pd
import collections

def countFunction(words, word_to_search):
    def _countFunction():
        return words.count(word_to_search)
    return _countFunction

def counterObject(words, word_to_search):
    def _counterObject():
        return collections.Counter(words)[word_to_search]
    return _counterObject

def bruteForce(words, word_to_search):
    def _bruteForce():
        counts = []
        count = 0
        for word in words:
            if word == word_to_search:
              # update counter variable
                count = count + 1
            counts.append(count)
        return counts
    return _bruteForce
    
import timeit

words = ['hello', 'goodbye', 'howdy', 'hello', 'hello', 'hi', 'bye']

print("Time to execute:\n")
print("count(): %ss" % timeit.Timer(countFunction(words, 'hello')).timeit(1000))
print("Counter: %ss" % timeit.Timer(counterObject(words, 'hello')).timeit(1000))
print("Brute Force: %ss" % timeit.Timer(bruteForce(words, 'hello')).timeit(1000))

Lo que resulta en:

1
2
3
4
5
Time to execute:

count(): 0.0001573999998072395s
Counter: 0.0019498999999996158s
Brute Force: 0.0005682000000888365s

Los métodos de búsqueda de fuerza bruta y count() superan a Counter, principalmente porque Counter cuenta inherentemente todas las palabras en lugar de una.

Conclusión

En esta guía, exploramos cómo encontrar la ocurrencia de la palabra en una lista de Python, evaluar la eficiencia de cada solución y sopesar cuándo cada una es más adecuada.