簡體   English   中英

如何在[0:1]中將字符串哈希到浮點數?

[英]How to hash strings into a float in [0:1]?

我有一個包含多個字符串的數據集。 我想將這些字符串中的每一個與一個浮點數相關聯,“隨機”分布在[0:1]范圍內。 例子:

>>> myfunction(string_1)
0.26756754
>>> myfunction(string_2)
0.86764534

random不能滿足我的需要,因為它不會將任何字符串作為輸入/確定性參數。 我正在尋找更像哈希函數的東西。

快速便攜的解決方案:

from zlib import crc32

def bytes_to_float(b):
    return float(crc32(b) & 0xffffffff) / 2**32

這會將字節字符串轉換為介於0.0和1.0之間的浮點數。 如果您使用的是unicode字符串(例如,在python 3中),那么您需要對其進行編碼:

def str_to_float(s, encoding="utf-8"):
    return bytes_to_float(s.encode(encoding))

>>> str_to_float(u"café")
0.5963937465567142

這應該在任何機器和任何版本的python上給出相同的結果(在python 2.7和3.5上測試)。

注意: & 0xffffffff用於保證unsigned int結果。 這是必需的,因為根據python版本, crc32(b)可能會返回有符號或無符號的int。

編輯

如果你想要比CRC32更“隨機”的東西,你可以使用哈希函數,例如SHA256:

from struct import unpack
from hashlib import sha256

def bytes_to_float(b):
    return float(unpack('L', sha256(b).digest()[:8])[0]) / 2**64

性能測試

            String length
Function    7       70      700     7000
b2f_crc32   0.34    0.38    0.87    5.59    
b2f_md5     0.96    1.08    2.11    11.13   
b2f_sha1    0.99    1.07    1.76    8.37    
b2f_sha256  1.11    1.20    2.60    16.44   
b2f_rnd     6.59    6.55    6.59    6.60    

基本上,CRC32解決方案是短串的最快速度(比@ user3030010的隨機= RND解決方案快18倍)。 它大約比SHA256快3倍,無論字符串長度如何。 SHA256比MD5慢,慢於SHA1(非常短的字符串除外)。 但是,RND選項不依賴於字符串長度,因此當字符串很長時,它可能是最快的選項(但請參閱我對@ user3030010的答案的評論):在我的計算機上,對於長度超過2500的字符串,它勝過SHA256字符,對於長度超過8000個字符的字符串,它勝過CRC32。

這是代碼,使用timeit.timeit()

from __future__ import print_function
[...] # define b2f_crc32, b2f_md5 and so on.
for func in ("b2f_crc32", "b2f_md5", "b2f_sha1", "b2f_sha256", "b2f_rnd"):
  for length in (7, 70, 700, 7000):
    t = timeit('b2f(b"%s")'%(b"x"*length),
               'from __main__ import %s as b2f' % func)
    print("%.2f"%t, end="\t")
  print()

你可以嘗試這樣的事情:

import random
random.seed(hash(your_string))
random.random()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM