2014-02-22 46 views
3

我試圖用MRJob實現一個非常基本的wordcount示例。一切工作正常使用ASCII輸入,但是當我西里爾話混入輸入,我得到這樣的事情作爲一個輸出python map在西里爾文文本中簡化wordcount

"\u043c\u0438\u0440" 1 
"again!" 1 
"hello" 2 
"world" 1 

據我瞭解,上面第一行是西里爾文字的編碼單發生「мир」,這是關於我的示例輸入文本的正確結果。這裏是MR代碼

class MRWordCount(MRJob): 

    def mapper(self, key, line): 
     line = line.decode('cp1251').strip() 
     words = line.split() 
     for term in words: 
      yield term, 1 

    def reducer(self, term, howmany): 
     yield term, sum(howmany) 

if __name__ == '__main__': 
     MRWordCount.run() 

我在Windows上使用Python 2.7和mrjob 0.4.2。 我的問題是:

a)我如何設法正確生產可讀西里爾文輸入西里爾文輸入? b)這種行爲的根源是什麼 - 它是由於python/MR版本還是預計在非windows上以不同方式工作 - 任何線索?

我再生蟒蛇-c「打印u'мир'」的輸出

Traceback (most recent call last): 
File "<string>", line 1, in <module> 
File "C:\Python27\lib\encodings\cp866.py", line 12, in encode 
return codecs.charmap_encode(input,errors,encoding_map) 
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-2: character maps to <undefined> 
+0

你的機器上的命令的輸出是什麼:'python -c「print'мир',u'мир'」'? – jfs

+0

UnicodeEncodeError:'charmap'編解碼器無法對位置0-2中的字符進行編碼:字符映射到 Anton

+0

嘗試使用unicode轉義編寫Unicode文字:'python -c「print'мир',u'\ u043c \ u0438 \ u0440' 「'。如果它也產生錯誤,則將'PYTHONIOENCODING' envvar設置爲控制檯使用的字符編碼,例如'cp1251'或'cp866'。可能,爲了避免從Python打印非ASCII字符到Windows控制檯的問題,'mrjob'調用'.encode('unicode-escape')'或者它可能使用JSON文本作爲輸入/輸出(也使用類似的轉義)。 – jfs

回答

2

在Python 2.x中其可讀性打印這一點,你需要明確地告訴解釋,這是一個Unicode字符串:

>>> print(u"\u043c\u0438\u0440") # note leading u 
мир 

要將字符串轉換成Unicode字符串,用unicode

>>> print(unicode("\u043c\u0438\u0440", "unicode_escape")) 
мир 
+0

謝謝,但是將此添加到reducer中導致'TypeError:解碼Unicode不受支持' – Anton

+0

如果'MRJob'不支持,您可以將此作爲後處理步驟添加到結果中。 – jonrsharpe

+0

這是可能的,但我試圖避免這一點。 – Anton

0

要打印到您的控制檯,您需要將字符編碼爲終端理解的編碼。大部分時間將是UTF-8:print u"\u043c\u0438\u0440".encode("utf-8"),但在Windows上,您可能需要使用另一個(cp1251,也許?)。

+0

謝謝,但是這不會產生可讀的西里爾輸出,無論是打印到控制檯還是文件(使用'--no-output'選項) – Anton