如何正确计算带有变音符号的字母在文本中的数量?

8
我希望能够找到一种方法来计算文本中不同字母的频率,其中一些字母使用了变音符号。例如,文本中既使用了“å”,又使用了“ą̊”(U+00E5 U+0328),需要分别计算其频率。
我该怎么做呢?
我尝试使用Counter集合,使用utf8格式打开文件,使用text.split()list(text)拆分文本字符串,但Python仍将“å”和“ą̊”视为相同的字母!
2个回答

8
这里的问题是unicode文本(忘记utf-8,我指的是将数据解码为适当的Python 3字符串后)对于某些字符使用多个unicode代码点:例如 'ą̊' 有两个标记,因此在正确规范化后,“ą”和“å”都可以作为单个字符存在,但是一个带有两个标记的字符必须使用unicode中的一个“组合标记”字符。
这意味着Python的Counter单独处理无法处理它,至少需要额外的一步。在Python代码中,查找这些标记字符的方法是使用unicodedata.category - 它并不友好,只返回类别的两个字符标识符
因此,我认为可以采用一些“纯Python”代码将您的文本预处理为列表,其中每个字符及其标记都被规范化,然后Counter可以完成其工作。
可能是以下内容:
import unicodedata
from collections import Counter

characters = []

text = ...

# Decompose all characters into plain letters + marking diacritics:
text = unicodedata.normalize("NFD", text)
for character in text:
    if unicodedata.category(character)[0] == "M": 
        # character is a composing mark, so agregate it with
        # previous character
        characters[-1] += character
    else:
        characters.append(character)

counting = Counter(characters)

(请注意,上面的代码片段未考虑潜在的格式不良的文本片段,该片段可能以标记字符在位置0开始)

在读取if unicodedata.category("character")[0] == "M":这行代码时,应注意不要将character放在引号内,因为它是一个变量。 - olooney
1
非常感谢!我已经测试过了,它的表现很棒,即使是带有双标记的字母也可以正常工作 :)我不得不查看 unicodedata.normalizeunicodedata.category,所以这里提供链接,如果其他人需要的话: https://docs.python.org/2/library/unicodedata.html#unicodedata.normalize https://docs.python.org/2/library/unicodedata.html#unicodedata.category http://www.fileformat.info/info/unicode/category/index.htm非常感谢您的帮助! - user11448

0

在计数之前,您可以使用另一个字符替换特殊字符,该字符可以由单个代码点表示。只需确保替换字符不会出现在语料库中。

text.replace('ą̊', 'Ʒ').replace('Ą̊', 'ʒ')

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