Word Frequency Counter with Counts and Percentages
This word frequency counter lists every distinct word in your text, with how many times it occurs and its share of the total, most frequent first. Writers use it to find overused words, SEO editors to check keyword use, and students and researchers to explore vocabulary.
Example
Input: To be, or not to be, that is the question. Whether tis nobler
in the mind to suffer the slings and arrows.
# Phrase Count Density
1 the 3 13.64%
2 to 3 13.64%
3 be 2 9.09%
4 and 1 4.55%
5 arrows 1 4.55%
...
Unique words: 17 · Words: 22
Words with the same count are listed alphabetically. Each density is the word's count divided by the total number of words in the text: 3 ÷ 22 = 13.64%. The Unique words and Words cards beside the text box give the two totals.
Options explained
- 1 word / 2 words / 3 words: switches the table from single words to two- or three-word phrases. Only phrases that occur at least twice are listed, and a phrase never runs across a sentence end, colon, semicolon, bracket, double quotation mark or line break. In the example above, 2 words lists “to be” with a count of 2.
- Ignore stop words (off by default on this page): hides 142 frequent English function words such as the, and, to, of, is, it, you, we and not, and also numbers written in digits. In the example above only 8 words remain, and “question”, “nobler” and “arrows” become visible. In the phrase views it hides any phrase that starts or ends with a stop word.
- Show all: the table starts with the 20 most frequent entries; this button expands it to the full list, up to 1,000 rows. Copy CSV copies every row as
phrase,count,density.
Capitalization is always ignored: “The” and “the” are merged into one lowercase entry, and there is no minimum word length setting.
How words are recognized
A word is a run of letters or digits in any alphabet, and apostrophes or hyphens inside a word keep it together, so “don't” and “e-mail” are single entries. Punctuation around words is ignored, so you do not need to strip it first.
The counter does not reduce words to a stem. “run”, “runs” and “running” are three separate entries; add their counts together if you want the total for the word family.
Keyword density
Keyword density is how often a keyword appears relative to the total word count. The Density column is always measured against every word in the text, so ticking Ignore stop words hides rows but does not change the percentages of the words that remain. In the phrase views each word of the phrase counts: “to be” found twice in the 22-word example has a density of 2 × 2 ÷ 22 = 18.18%. If you mainly need the total word count, the Word Counter puts it first.
There is no ideal density to aim for. Search engines treat repeating a keyword unnaturally as keyword stuffing, so use the table to catch repetition, not to hit a target percentage.
Other uses
- Spotting crutch words such as “just”, “really” or “very” in a draft.
- Comparing the vocabulary of two texts or authors.
- Building tag clouds or keyword lists; sort the result alphabetically with the Word Sorter if needed.
- Checking survey answers or reviews for recurring themes, after tidying the input with the Text Cleaner.
Privacy
The analysis runs in your browser; the text is not uploaded unless you click Save & Share to create a link.
Word frequency counter in Python
collections.Counter is the standard-library way to build a word frequency counter in Python: it is a dictionary subclass that maps each word to its count, and most_common() returns the top entries. The mistake is feeding it text.split(), which leaves punctuation attached and keeps capitals, so "hat." and "hat", or "The" and "the", are counted separately. Lowercase the text and pull out the words with a regular expression instead. With a plain dictionary, the equivalent line is counts[word] = counts.get(word, 0) + 1.
import re
from collections import Counter
text = "The cat and the hat. The cat sat; the cat's hat fell - don't laugh!"
# Letters and digits, with apostrophes or hyphens allowed inside a word
words = re.findall(r"[^\W_]+(?:['’-][^\W_]+)*", text.lower())
counts = Counter(words) # a dict subclass: {word: count}
total = sum(counts.values())
for word, count in sorted(counts.items(), key=lambda item: (-item[1], item[0])):
print(f"{word:<8}{count:>3}{count / total:>9.2%}")
print(dict(counts.most_common(3)))
Paste the same sentence into the counter above and you get the same counts and shares, in the same order.