2017-09-30 15 views
0

私はHadoop/MapReduceを使用してムービーの推奨事項を作成しています。
私は、MapReduceプロセスを実装するためにpythonのみを使用しています。コンソールへのpython出力の制御

私は基本的に、マッパーとレデューサーを別々に実行し、マッパーからレデューサーへのコンソール出力を使用しています。

私が問題になっているのは、Pythonが端末の文字列として値を出力するということです。数字を使って作業している場合、数値は文字列として出力されるため、変換が簡単になりますサーバーに負荷がかかります。

この問題を解決するにはどうすればいいですか?純粋なPythonとサードパーティ製のライブラリを使用しないで実装することを検討しています。ここで

import sys 

def mapper(): 
    ''' 
     From Mapper1 : we need only UserID , (MovieID , rating) 
     as output. 
    ''' 

    #* First mapper 

    # Read input line 
    for line in sys.stdin: 
     # Strip whitespace and delimiter - ',' 
     print line 
     data = line.strip().split(',') 

     if len(data) == 4: 
      # Using array to print out values 
      # Direct printing , makes python interpret 
      # values with comma in between as tuples 
      # tempout = [] 
      userid , movieid , rating , timestamp = data 
      # tempout.append(userid) 
      # tempout.append((movieid , float(rating))) 
      # print tempout 

      # 
      print "{0},({1},{2})".format(userid , movieid , rating) 

は減速print文です:

def reducer(): 

    oldKey = None 
    rating_arr = [] 

    for line in sys.stdin: 
     # So we'll recieve user, (movie,rating) 
     # We need to group the tuples for unique users 
     # we'll append the tuples to an array 
     # Given that we have two data points , we'll split the 
     # data at only first occurance of ',' 
     # This splits the string only at first comma 

     data = line.strip().split(',',1) 
     # print len(data) , data 
     # check for 2 data values 
     if len(data) != 2: 
      continue 

     x , y = data 

     if oldKey and oldKey != x: 

      print "{0},{1}".format(oldKey , rating_arr) 
      oldKey = x 
      rating_arr = [] 
     oldKey = x 
     rating_arr.append(y) 
     # print rating_arr 
    if oldKey != None: 
     print "{0},{1}".format(oldKey , rating_arr) 

`

入力は次のとおりです。

671,(4973,4.5)\n671,(4993,5.0)\n670,(4995,4.0)

出力は次のとおりです。

671,['(4973,4.5)', '(4993,5.0)'] 
670,['(4995,4.0)'] 

タプルはそのままで、文字列は必要ありません。

+1

Pythonはないでしょう自動的にリスト内のタプルを文字列に変換すると、あなたの問題は上流にあるようです。 – roganjosh

+0

ここには欠けているコードがたくさんあります。それがなければ、私たちはあまり使用されません。 – pstatix

+0

更新されたコードを確認してください –

答えて

1

データが文字列であり、次にyを分割して割り当てたという事実は、の文字列であるです。

タプルの生の値を数値として使用するには、数値を解析する必要があります。

ast.literal_evalが役に立ちます。 Hadoopのストリーミングと

あなたはPySparkに切り替えたい場合たとえば、

In [1]: line = """671,(4973,4.5)""" 

In [2]: data = line.strip().split(',',1) 

In [3]: data 
Out[3]: ['671', '(4973,4.5)'] 

In [4]: x , y = data 

In [5]: type(y) 
Out[5]: str 

In [6]: import ast 

In [7]: y = ast.literal_eval(y) 

In [8]: y 
Out[8]: (4973, 4.5) 

In [9]: type(y) 
Out[9]: tuple 

In [10]: type(y[0]) 
Out[10]: int 

さて、あなたはより多くの変数/オブジェクトタイプのコントロールではなく、すべての文字列を持っているでしょう

+0

申し訳ありませんが動作していないようですが、不正な文字列エラーが発生します。 かっこで問題が発生しているようです。 それをstrに変換してからliteral_evalを使用すると、リスト内の値は文字列として解釈されます。アポストロフィを参照してください。 私が試してみるべきことは何ですか? 異なるマッパーとレデューサーの間でデータを直接渡す方法はありますか? –

+0

明らかに、 'print"%d "%rating_arr'は、配列が** d **エキュール番号ではないので動作しません。'rating_arr'を直接印刷する必要があります –

+0

しかし、あなたのレデューサーは一貫した出力を持つべきです。 'print {0}、{1}'。format(oldKey、rating_arr) 'をもう一度やり直す必要がある場合は、 –

関連する問題