计算列表中单词出现的频率并按频率排序

92

我正在使用Python 3.3。

我需要创建两个列表,一个是单词的唯一列表,另一个是单词频率的列表。

我必须根据频率列表对唯一单词列表进行排序,以便具有最高频率的单词排在列表的第一位。

我已经有了文本中的设计,但不确定如何在Python中实现。

到目前为止,我发现的方法都使用了Counter或字典,但我们还没有学习这些内容。我已经从包含所有单词的文件创建了列表,但不知道如何找到列表中每个单词的频率。我知道我需要循环来完成这个任务,但无法想出如何实现。

以下是基本设计:

 original list = ["the", "car",....]
 newlst = []
 frequency = []
 for word in the original list
       if word not in newlst:
           newlst.append(word)
           set frequency = 1
       else
           increase the frequency
 sort newlst based on frequency list 

1
我们很难知道你掌握了哪些知识。你学过set吗?列表的count方法呢?等等。请用有意义的术语描述问题。 - roippi
2
为什么不允许使用未被教授的东西?现在提前学习是不被鼓励的吗? - John La Rooy
一个Trie将是一个相当高效的替代方法。你可以只用列表建立一个。 - John La Rooy
2
请考虑接受一个答案。 - PatrickT
15个回答

196

使用这个

from collections import Counter
list1=['apple','egg','apple','banana','egg','apple']
counts = Counter(list1)
print(counts)
# Counter({'apple': 3, 'egg': 2, 'banana': 1})

5
恒星解决方案 - Chris Dormani
仍然在2021年保持强大,继续前进。 - Arka Mukherjee

55
你可以使用

from collections import Counter

它支持Python 2.7,更多信息请点击这里

>>>c = Counter('abracadabra')
>>>c.most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

使用字典

>>>d={1:'one', 2:'one', 3:'two'}
>>>c = Counter(d.values())
[('one', 2), ('two', 1)]

但是,您必须首先读取文件,然后将其转换为字典。

2. 这是Python文档的示例,使用了re和Counter。

# Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]

20
words = file("test.txt", "r").read().split() #read the words into a list.
uniqWords = sorted(set(words)) #remove duplicate words and sort
for word in uniqWords:
    print words.count(word), word

一个伟大的Pythonic方式! - incalite
6
你测试过这段代码能否处理大文件吗?如果文件太大,会花费大量时间。使用集合会更高效。 - Tony Wang
这种方法不如使用Counter。当你执行set(words)时,你会不必要地丢弃计数,因此每次需要计数时都必须使用words.count(word)进行查找,这对于大文本来说效率很低。 - smci

13

Pandas的回答:

import pandas as pd
original_list = ["the", "car", "is", "red", "red", "red", "yes", "it", "is", "is", "is"]
pd.Series(original_list).value_counts()

如果你想按升序排序,那么只需要:

pd.Series(original_list).value_counts().sort_values(ascending=True)

9

这是一种不使用集合的算法的另一种解决方案:

def countWords(A):
   dic={}
   for x in A:
       if not x in  dic:        #Python 2.7: if not dic.has_key(x):
          dic[x] = A.count(x)
   return dic

dic = countWords(['apple','egg','apple','banana','egg','apple'])
sorted_items=sorted(dic.items())   # if you want it sorted

5
你可以使用reduce() - 一种函数式的方式。
words = "apple banana apple strawberry banana lemon"
reduce( lambda d, c: d.update([(c, d.get(c,0)+1)]) or d, words.split(), {})

返回:

{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}

5

一种方法是创建一个列表,其中每个子列表包含一个单词和计数:

list1 = []    #this is your original list of words
list2 = []    #this is a new list

for word in list1:
    if word in list2:
        list2.index(word)[1] += 1
    else:
        list2.append([word,0])

或者更高效地说:
for word in list1:
    try:
        list2.index(word)[1] += 1
    except:
        list2.append([word,0])

这种方法比使用字典效率低,但使用的是更基础的概念。


4
使用计数器是最好的方式,但如果您不想这样做,您可以按照以下方式自己实现。
# The list you already have
word_list = ['words', ..., 'other', 'words']
# Get a set of unique words from the list
word_set = set(word_list)
# create your frequency dictionary
freq = {}
# iterate through them, once per unique word.
for word in word_set:
    freq[word] = word_list.count(word) / float(len(word_list))

freq将包含您已经拥有的列表中每个单词的频率。

您需要在其中使用float将整数转换为浮点数,以便结果值为浮点数。

编辑:

如果您不能使用dict或set,则还有另一种不那么高效的方法:

# The list you already have
word_list = ['words', ..., 'other', 'words']
unique_words = []
for word in word_list:
    if word not in unique_words:
        unique_words += [word]
word_frequencies = []
for word in unique_words:
    word_frequencies += [float(word_list.count(word)) / len(word_list)]
for i in range(len(unique_words)):
    print(unique_words[i] + ": " + word_frequencies[i])
< p > unique_wordsword_frequencies的索引将匹配。


1

这里是支持您问题的代码 is_char() 用于验证字符串计数,Hashmap 是 Python 中的字典

def is_word(word):
   cnt =0
   for c in word:

      if 'a' <= c <='z' or 'A' <= c <= 'Z' or '0' <= c <= '9' or c == '$':
          cnt +=1
   if cnt==len(word):
      return True
  return False

def words_freq(s):
  d={}
  for i in s.split():
    if is_word(i):
        if i in d:
            d[i] +=1
        else:
            d[i] = 1
   return d

 print(words_freq('the the sky$ is blue not green'))

1

简单的方法

d = {}
l = ['Hi','Hello','Hey','Hello']
for a in l:
    d[a] = l.count(a)
print(d)
Output : {'Hi': 1, 'Hello': 2, 'Hey': 1} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接