2016-08-26 110 views
5

Hem Python hem de Scala'da MurmurHash dizelerine ihtiyacım var. Ancak çok farklı sonuçlar veriyorlar. Scala'nın yerleşik MurmurHash3 kütüphanesi, çevrimiçi olanlar da dahil olmak üzere denediğim diğer kitaplıklar ile aynı sonuçları vermemektedir. Garip olan şey, tek bir karakterle eşleşiyor gibi görünüyor, ancak birden fazla karakter değil. İşte bazı örnekler:Scala MurmurHash3 kütüphanesi eşleşmiyor Python mmh3 library

Python:

mmh3.hash('string', 0) 
res: -1390314837 

Scala: Ben Java imzaladı biliyorum ve C uygulaması piton sarma olduğu gibi imzalı ve imzasız ints ile oynarken denedi

MurmurHash3.stringHash("string", 0) 
res: 379569354 

imzasız kullanarak. Ancak, işaretli bir aralığa dönüştürmek için NumPy'yi kullanmamız bile bize yardımcı olmaz. Burada gidiyor olabilir ne

http://murmurhash.shorelabs.com/

Herhangi bir fikir: Bu site piton uygulanması yaramış?

cevap

3

Scala, UTF-16 olarak kodlanmış Java dizelerini kullanır. Bunlar bir defada Int; Python bir char* (8 bit) kullanır, bu nedenle iki yerine bir defada dört karakter halinde paketler.

Düzenleme: Scala ayrıca, charterleri MSB düzeninde, yani (s.charAt(i) << 16) | (s.charAt(i+1))'da paketler. Bir dizi şorta geçmeniz ve tam olarak aynı cevabı almak için gerçekten önemliyse her bir çiftini değiştirmeniz gerekebilir. (Ya da Scala kodunu Python'a veya tersi port edin.) Aynı zamanda dize uzunluğu ile sonuçlanır; Hiç değilse, Python'un uzunluk verilerini nasıl dahil ettiğinden emin değilim. (Eğer dizeleri "\u0000" ve "\u0000\u0000" ayırt edebilmek amacıyla bu önemlidir.)

+1

Yani, eğer sorun buysa, 'string'i python'da utf-16'ya çevirmek, Scala ile aynı sonucu döndürmez mi? Python: 'string'.encode ('UTF-16')' – patrickbarker

+1

@patrickbarker - Sadece Python başka bir veriyi paketlemezse ve bunları birleştirirken MSB düzenindeki karakterleri (şort) paketlerse, Scala uygulaması yapar. –

0

bu 4 kişilik gruplar halinde karma miksere Scala'nın MurmurHash3.stringHash ve MurmurHash3.bytesHash

MurmurHash3.bytesHash ve Python en mmh3.hash geçiş karakterleri arasında uygulanmasında farkından kaynaklanmaktadır Eğer PYT sonuçlarını ihtiyacın olursa

import scala.util.hashing.MurmurHash3 

val testString = "FiddlyString" 

MurmurHash3.stringHash(testString)   /* Returns an int */ 
MurmurHash3.bytesHash(testString.getBytes()) /* Returns a different int */ 

: ama MurmurHash3.stringHash 2. Bu gruplar halinde karakterleri karıştırır iki hash fonksiyonları tamamen farklı çıkışları dönmek anlamına gelir hon ve Scala'nın MurmurHash3 değerleri tam olarak uyacak şekilde: Ben wc-duck's pure-python implementation of MurmurHash3 uyarlanan pymmh3.string_hash fonksiyonu ile mmh3.hash()

  • Kullanım MurmurHash3.stringHash ile

    • kullanın MurmurHash3.bytesHash(myString.getBytes()) yerine MurmurHash3.stringHash() Scala'nın MurmurHash3.stringHash

    Ben ile uyumlu olacak şekilde d özellikle ilk kullanım seçeneğini önerirseniz, kullanım durumunuz daha iyi bir performans gerektiriyorsa veya