python单词中字母的位置频率词典
python position frequency dictionary of letters in words
为了有效地获取字母的频率(给定字母 ABC
在字典中的字符串 code
我可以创建一个函数 a-la (Python 3) :
def freq(code):
return{n: code.count(n)/float(len(code)) for n in 'ABC'}
然后
code='ABBBC'
freq(code)
给我
{'A': 0.2, 'C': 0.2, 'B': 0.6}
但是我怎样才能得到不等长字符串列表中每个位置的频率?例如 mcode=['AAB', 'AA', 'ABC', '']
应该给我一个嵌套结构,如字典列表(其中每个字典是每个位置的频率):
[{'A': 1.0, 'C': 0.0, 'B': 0.0},
{'A': 0.66, 'C': 0.0, 'B': 0.33},
{'A': 0.0, 'C': 0.5, 'B': 0.5}]
我不知道如何计算所有字符串中每个位置的频率,并将其包装在列表理解中。受其他 SO 的启发,用于字数统计,例如讨论得很好 post Python: count frequency of words in a list 我相信来自 collections
的 Counter 模块可能会有所帮助。
这样理解 - 将 mcode 字符串写在不同的行上:
AAB
AA
ABC
那么我需要的是字典列表中字母表 ABC 的列频率(AAA、AAB、BC),其中每个列表元素是每列 ABC 的频率。
示例,这些步骤在评论中进行了简短说明。模块 collections
的 Counter
未被使用,因为位置的映射还包含字符,这些字符不存在于该位置并且频率顺序似乎无关紧要。
def freq(*words):
# All dictionaries contain all characters as keys, even
# if a characters is not present at a position.
# Create a sorted list of characters in chars.
chars = set()
for word in words:
chars |= set(word)
chars = sorted(chars)
# Get the number of positions.
max_position = max(len(word) for word in words)
# Initialize the result list of dictionaries.
result = [
dict((char, 0) for char in chars)
for position in range(max_position)
]
# Count characters.
for word in words:
for position in range(len(word)):
result[position][word[position]] += 1
# Change to frequencies
for position in range(max_position):
count = sum(result[position].values())
for char in chars:
result[position][char] /= count # float(count) for Python 2
return result
# Testing
from pprint import pprint
mcode = ['AAB', 'AA', 'ABC', '']
pprint(freq(*mcode))
结果(Python 3):
[{'A': 1.0, 'B': 0.0, 'C': 0.0},
{'A': 0.6666666666666666, 'B': 0.3333333333333333, 'C': 0.0},
{'A': 0.0, 'B': 0.5, 'C': 0.5}]
在Python3.6中,字典偶数排序;早期版本可以使用 collections
中的 OrderedDict
而不是 dict
.
您的代码根本没有效率:
- 您首先需要定义要计数的字母
- 您需要为每个不同的字母解析字符串
你可以直接使用 Counter
:
import itertools
from collections import Counter
mcode=['AAB', 'AA', 'ABC', '']
all_letters = set(''.join(mcode))
def freq(code):
code = [letter for letter in code if letter is not None]
n = len(code)
counter = Counter(code)
return {letter: counter[letter]/n for letter in all_letters}
print([freq(x) for x in itertools.zip_longest(*mcode)])
# [{'A': 1.0, 'C': 0.0, 'B': 0.0}, {'A': 0.6666666666666666, 'C': 0.0, 'B': 0.3333333333333333}, {'A': 0.0, 'C': 0.5, 'B': 0.5}]
对于 Python2,您可以使用 itertools.izip_longest
。
更短的解决方案:
from itertools import zip_longest
def freq(code):
l = len(code) - code.count(None)
return {n: code.count(n)/l for n in 'ABC'}
mcode=['AAB', 'AA', 'ABC', '']
results = [ freq(code) for code in zip_longest(*mcode) ]
print(results)
为了有效地获取字母的频率(给定字母 ABC
在字典中的字符串 code
我可以创建一个函数 a-la (Python 3) :
def freq(code):
return{n: code.count(n)/float(len(code)) for n in 'ABC'}
然后
code='ABBBC'
freq(code)
给我
{'A': 0.2, 'C': 0.2, 'B': 0.6}
但是我怎样才能得到不等长字符串列表中每个位置的频率?例如 mcode=['AAB', 'AA', 'ABC', '']
应该给我一个嵌套结构,如字典列表(其中每个字典是每个位置的频率):
[{'A': 1.0, 'C': 0.0, 'B': 0.0},
{'A': 0.66, 'C': 0.0, 'B': 0.33},
{'A': 0.0, 'C': 0.5, 'B': 0.5}]
我不知道如何计算所有字符串中每个位置的频率,并将其包装在列表理解中。受其他 SO 的启发,用于字数统计,例如讨论得很好 post Python: count frequency of words in a list 我相信来自 collections
的 Counter 模块可能会有所帮助。
这样理解 - 将 mcode 字符串写在不同的行上:
AAB
AA
ABC
那么我需要的是字典列表中字母表 ABC 的列频率(AAA、AAB、BC),其中每个列表元素是每列 ABC 的频率。
示例,这些步骤在评论中进行了简短说明。模块 collections
的 Counter
未被使用,因为位置的映射还包含字符,这些字符不存在于该位置并且频率顺序似乎无关紧要。
def freq(*words):
# All dictionaries contain all characters as keys, even
# if a characters is not present at a position.
# Create a sorted list of characters in chars.
chars = set()
for word in words:
chars |= set(word)
chars = sorted(chars)
# Get the number of positions.
max_position = max(len(word) for word in words)
# Initialize the result list of dictionaries.
result = [
dict((char, 0) for char in chars)
for position in range(max_position)
]
# Count characters.
for word in words:
for position in range(len(word)):
result[position][word[position]] += 1
# Change to frequencies
for position in range(max_position):
count = sum(result[position].values())
for char in chars:
result[position][char] /= count # float(count) for Python 2
return result
# Testing
from pprint import pprint
mcode = ['AAB', 'AA', 'ABC', '']
pprint(freq(*mcode))
结果(Python 3):
[{'A': 1.0, 'B': 0.0, 'C': 0.0},
{'A': 0.6666666666666666, 'B': 0.3333333333333333, 'C': 0.0},
{'A': 0.0, 'B': 0.5, 'C': 0.5}]
在Python3.6中,字典偶数排序;早期版本可以使用 collections
中的 OrderedDict
而不是 dict
.
您的代码根本没有效率:
- 您首先需要定义要计数的字母
- 您需要为每个不同的字母解析字符串
你可以直接使用 Counter
:
import itertools
from collections import Counter
mcode=['AAB', 'AA', 'ABC', '']
all_letters = set(''.join(mcode))
def freq(code):
code = [letter for letter in code if letter is not None]
n = len(code)
counter = Counter(code)
return {letter: counter[letter]/n for letter in all_letters}
print([freq(x) for x in itertools.zip_longest(*mcode)])
# [{'A': 1.0, 'C': 0.0, 'B': 0.0}, {'A': 0.6666666666666666, 'C': 0.0, 'B': 0.3333333333333333}, {'A': 0.0, 'C': 0.5, 'B': 0.5}]
对于 Python2,您可以使用 itertools.izip_longest
。
更短的解决方案:
from itertools import zip_longest
def freq(code):
l = len(code) - code.count(None)
return {n: code.count(n)/l for n in 'ABC'}
mcode=['AAB', 'AA', 'ABC', '']
results = [ freq(code) for code in zip_longest(*mcode) ]
print(results)