如何用Python计算段落中英文单词的百分比

3 投票
5 回答
3836 浏览
提问于 2025-04-18 15:10

假设我有一段包含不同语言的文字,比如:

这是一段英文。 这是在英国段。 Это пункт на английском языке. این بند در زبان انگلیسی است.

我想计算这段文字中有多少百分比是英文单词。所以我想问一下,怎么用Python来实现这个计算。

5 个回答

0

一个很有用的数据结构可以帮助我们做这种事情,那就是字典树(trie)

如果我们使用我修改过的英文单词列表,来自另一篇帖子

import os
import json
import urllib3
 
eng_trie = {}

def add_to_trie(trie: dict, word: str, lower: bool=False) -> dict:
    if lower:
        word = word.lower()
    letter = word[:1]

    if len(word) == 1:
        # This is the last letter, add a terminator
        trie[word] = {**trie.get(word, {}), "EOW": True}
    else:
        if not trie.get(letter):
            trie[letter] = {}
        trie[letter] = add_to_trie(trie[letter], word[1:])
    return trie

if __name__ == "__main__":
    output_file = "./data/words.json"
    url = "https://github.com/JonathanRys/data-repository/blob/master/data/words.txt?raw=true"
    response = urllib3.request("GET", url)
    if response.status:
        for word in [word.strip() for word in response.data.decode().split('\n')]:
            if word:
                try:
                    add_to_trie(eng_trie, word, lower=True)
                except Exception as e:
                    print(f'ERROR for word "{word}": {e}')
    
    with open(output_file, 'w') as f:
        print(json.dumps(eng_trie), file=f)

那么使用它的方法是

import json

json_trie = './data/words.json'

def get_data(file: str) -> dict:
    with open(file) as f:
        trie = json.loads(f.read())
    return trie

def check(word: str, trie: dict=get_data(json_trie)) -> bool:
    if len(word) == 1:
        if trie.get(word):
            if trie.get(word).get('EOW'):
                return True
        else:
            return False
    if trie:
        next_trie = trie.get(word[:1])
        if next_trie:
            return check(word[1:], next_trie)
    return False

def is_english(word: str) -> bool:
    if not word:
        return False
    return check(word)

if __name__ == "__main__":
    words = ['albatross', 'run', 'winner', 'success', 'erwrtwaf', 'albat']
    for word in words:
        if is_english(word):
            print(f'English: {word}')
        else:
            print(f'Not English: {word}')
0

如果你所有用拉丁字母写的词都是英语的话,你可以使用正则表达式。

3

首先,你需要获取一份英文单词的列表。然后,逐行读取文件并进行计数!

import string
import urllib2

punctuation = set(string.punctuation)

eng_words_url = 'https://raw.github.com/eneko/data-repository/master/data/words.txt'
eng_words = urllib2.urlopen(eng_words_url).readlines()
eng_words = [w.strip().lower() for w in eng_words]

def remove_punc(str):
    return ''.join(c for c in str if c not in punctuation)

total_count = 0
eng_count = 0
with open('filename.txt') as f:
    for line in f:
        words = remove_punc(line).lower().split()
        total_count += len(words)
        eng_count += sum(1 for word in words if word.lower() in eng_words)

print '%s English words found' % eng_count
print '%s total words found' % total_count

percentage_eng = 0 if total_count == 0 else (float(eng_count) / total_count * 100)
print '%s%% of words were English' % percentage_eng

比如,这段文字就是你的示例文本:

这是一个英文段落。 这是在英国段。Это пункт на английском языке. این بند در زبان انگلیسی است.

当我在这段文字上运行上面的代码时,输出结果是这样的:

找到5个英文单词

总共找到16个单词

英文单词占总单词的31.25%

正如评论中提到的,由于中文单词之间没有空格,所以这个百分比是不正确的。实际上总共有22个单词,所以正确的百分比应该是22.7%。

3

有些人发现这个段落里有16个单词。但真的是这样吗?其中一个问题是,如果你想把英语单词的数量和句子里的单词数量进行比较,仅仅用英语的方法是比较困难的。找出英语单词的数量相对简单,但第二部分,也就是找出句子里的总单词数就难多了,因为你需要一些工具来搞清楚“这是在英国段”里到底有多少个单词,这样才能算出英语单词在段落中的比例。

可以试试使用自然语言工具包(NLTK)。NLTK是一个Python库(正在开发与Python3.0的兼容性),里面有你需要的功能,比如计算单词出现的频率、将字符串分割成单词等。此外,它还提供了英语语料库,你可以用来对比句子里的单词,看看哪些是英语单词。

与之配套的书籍《用Python进行自然语言处理》(Natural Language Processing with Python),适用于Python 2.x的第一版,可以在NLTK网站上免费获取。这本书是NLTK库和Python编程的入门书。Wordlist Corpus或Roget's Thesaurus Corpus可能会对你有帮助。另外,还有一个工具可以检测文本的语言。对于混合语言的情况,不太确定这个工具会怎么工作。

4

这个离线解决方案使用了pyenchant拼写检查模块:

# -*- coding: utf-8 -*
import enchant
dictionary = enchant.Dict("en_US")

paragraph = u"This is paragraph in English. 这是在英国段。Это пункт на английском языке. این بند در زبان انگلیسی است."

words = paragraph.split(" ")
en_count = 0.0
for word in words:
  if dictionary.check(word.strip()):
    en_count += 1

percent = en_count/len(words) if len(words) != 0 else 0
print str(percent) + "% english words"

输出结果:

31.25% english words

撰写回答