Python 将计数器中的整数替换为它们在总数中的百分比
Python replace integers in a Counter with their permillages of the total
我正在尝试使用马尔可夫链生成在任何词典中都找不到的可读的类似单词的随机字符串。
我从GCIDE拉取的总共105230个单词中拉取了大量ngram频率的数据,目前这些数据以Counter
格式存储(序列化为JSON
),并且利用马尔可夫链涉及从具有权重的集合中随机选择元素。
我已经找到了一种方法来进行加权随机抽样,就像这样:
random.choices(keys, weights=values, k=1)
(keys
和 values
是从 Counter
中提取的)
但我找到的所有教程都是使用 numpy
实现马尔可夫链,要使用此方法,我需要将整数转换为总数的千分率,并确保数字加起来等于 1.0。
正如我所说,我想要千分率格式的数字(float
小数点后三位)并且 float
s 必须加起来为 1.0 才能使 numpy
方法工作。
我可以将数字转换为 float
s,但由于 53 位双精度浮点格式固有的精度限制,这些数字并不总是相加为 1.0。
例如:
initcon = {'c': 7282,
'm': 6015,
'd': 5866,
'p': 5699,
's': 5294,
'b': 4103,
'r': 4097,
'h': 3926,
'l': 3352,
't': 2841,
'f': 2699,
'n': 2171,
'g': 2051,
'pr': 1991,
'v': 1626,
'tr': 1337,
'w': 1337,
'st': 1153,
'ch': 1121,
'cr': 827,
'br': 803,
'j': 799,
'sp': 746,
'gr': 694,
'k': 676,
'ph': 651,
'pl': 645,
'fl': 622,
'th': 594,
'sh': 572,
'q': 553,
'cl': 538,
'fr': 522,
'sc': 516,
'bl': 494,
'gl': 428,
'dr': 421,
'z': 376,
'wh': 338,
'str': 335,
'sl': 325,
'sw': 245,
'rh': 210,
'sk': 167,
'sn': 165,
'scr': 148,
'sm': 143,
'x': 143,
'chr': 141,
'kn': 139,
'thr': 125,
'sq': 124,
'ps': 123,
'wr': 113,
'sch': 106,
'tw': 95,
'spr': 73,
'spl': 72,
'shr': 66,
'sph': 65,
'chl': 54,
'pt': 51,
'gn': 49,
'phl': 41,
'scl': 39,
'gh': 37,
'pn': 37,
'phr': 33,
'kr': 30,
'kl': 22,
'dw': 16,
'kh': 15}
total = sum(initcon.values())
initcon = {k: v/total for k, v in initcon.items()}
print(sum(initcon.values()))
它打印 0.9999999999999999
.
如何使 initcon
中的数字相加正好为 1.0 并使它们都正好有 3 位小数?
我在工作中也遇到了类似的问题。我们发现保持总和等于 1 的唯一方法是添加一个额外的步骤。
之后
initcon = {k: v/total for k, v in initcon.items()}
你可以检查余数是多少,这样sum(initcon.values())==1
即
remainder = 1-sum(initcon.values())
然后您可以将此数字添加到任何键。您可以使用 random.choice
方法随机选择它。所以,最后,你会做这样的事情:
initcon[random_key]+=remainder
我正在尝试使用马尔可夫链生成在任何词典中都找不到的可读的类似单词的随机字符串。
我从GCIDE拉取的总共105230个单词中拉取了大量ngram频率的数据,目前这些数据以Counter
格式存储(序列化为JSON
),并且利用马尔可夫链涉及从具有权重的集合中随机选择元素。
我已经找到了一种方法来进行加权随机抽样,就像这样:
random.choices(keys, weights=values, k=1)
(keys
和 values
是从 Counter
中提取的)
但我找到的所有教程都是使用 numpy
实现马尔可夫链,要使用此方法,我需要将整数转换为总数的千分率,并确保数字加起来等于 1.0。
正如我所说,我想要千分率格式的数字(float
小数点后三位)并且 float
s 必须加起来为 1.0 才能使 numpy
方法工作。
我可以将数字转换为 float
s,但由于 53 位双精度浮点格式固有的精度限制,这些数字并不总是相加为 1.0。
例如:
initcon = {'c': 7282,
'm': 6015,
'd': 5866,
'p': 5699,
's': 5294,
'b': 4103,
'r': 4097,
'h': 3926,
'l': 3352,
't': 2841,
'f': 2699,
'n': 2171,
'g': 2051,
'pr': 1991,
'v': 1626,
'tr': 1337,
'w': 1337,
'st': 1153,
'ch': 1121,
'cr': 827,
'br': 803,
'j': 799,
'sp': 746,
'gr': 694,
'k': 676,
'ph': 651,
'pl': 645,
'fl': 622,
'th': 594,
'sh': 572,
'q': 553,
'cl': 538,
'fr': 522,
'sc': 516,
'bl': 494,
'gl': 428,
'dr': 421,
'z': 376,
'wh': 338,
'str': 335,
'sl': 325,
'sw': 245,
'rh': 210,
'sk': 167,
'sn': 165,
'scr': 148,
'sm': 143,
'x': 143,
'chr': 141,
'kn': 139,
'thr': 125,
'sq': 124,
'ps': 123,
'wr': 113,
'sch': 106,
'tw': 95,
'spr': 73,
'spl': 72,
'shr': 66,
'sph': 65,
'chl': 54,
'pt': 51,
'gn': 49,
'phl': 41,
'scl': 39,
'gh': 37,
'pn': 37,
'phr': 33,
'kr': 30,
'kl': 22,
'dw': 16,
'kh': 15}
total = sum(initcon.values())
initcon = {k: v/total for k, v in initcon.items()}
print(sum(initcon.values()))
它打印 0.9999999999999999
.
如何使 initcon
中的数字相加正好为 1.0 并使它们都正好有 3 位小数?
我在工作中也遇到了类似的问题。我们发现保持总和等于 1 的唯一方法是添加一个额外的步骤。
之后
initcon = {k: v/total for k, v in initcon.items()}
你可以检查余数是多少,这样sum(initcon.values())==1
即
remainder = 1-sum(initcon.values())
然后您可以将此数字添加到任何键。您可以使用 random.choice
方法随机选择它。所以,最后,你会做这样的事情:
initcon[random_key]+=remainder