2016-05-04 11 views
2

私はタイトル別の平均評価は性別3つの入力ファイルが必要なPython MapReduce Hadoopストリーミングジョブ?

である次のような出力を得るためにはPythonのMapReduceのHadoopストリーミングジョブを作成したい3つの小さなサンプル入力ファイル(実際のファイルがはるかに大きい)、

# File Name: books.txt 
# File Format: BookID|Title 
1|The Hunger Games 
2|To Kill a Mockingbird 
3|Pride and Prejudice 
4|Animal Farm 

# File Name: ratings.txt 
# File Format: ReaderID|BookID|Rating 
101|1|1 
102|2|2 
103|3|3 
104|4|4 
105|1|5 
106|2|1 
107|3|2 
108|4|3 

# File Name: readers.txt 
# File Format: ReaderID|Gender|PostCode|PreferComms 
101|M|1000|email 
102|F|1001|mobile 
103|M|1002|email 
104|F|1003|mobile 
105|M|1004|email 
106|F|1005|mobile 
107|M|1006|email 
108|F|1007|mobile 

を持っています

Animal Farm F 3.5 
Pride and Prejudice M 2.5 
The Hunger Games M 3 
To Kill a Mockingbird F 1.5 

私はそれを行くを与えたが、私はそのようにそれを正しく並べ替えることができないですので、Mapper部で立ち往生しています私はこのフォーラムを検索し、誰かがsolutionを指摘したが、それは代わりに3の2入力ファイルのためのものですレデューサーは、タイトル&の第1レコードを適切に認識することができる性別、次に集計を開始します。下のマッパーコード

#!/usr/bin/env python 
import sys 
for line in sys.stdin: 

    try: 

     ReaderID = "-1" 
     BookID = "-1" 
     Title = "-1" 
     Gender = "-1" 
     Rating = "-1" 

     line = line.strip() 

     splits = line.split("|") 

     if len(splits) == 2: 
      BookID = splits[0] 
      Title = splits[1] 
     elif len(splits) == 3: 
      ReaderID = splits[0] 
      BookID = splits[1] 
      Rating = splits[2] 
     else: 
      ReaderID = splits[0] 
      Gender = splits[1] 

     print('%s\t%s\t%s\t%s\t%s' % (BookID, Title, ReaderID, Rating, Gender)) 

    except: 
     pass 

PS:PythonとHadoop Streamingのみを使用する必要があります。 Dumbo、mrjobなどのPythonパッケージをインストールすることはできません。

事前に助けてください。 Lobbie

+1

私はhttps://allthingshadoop.com/2011/12/16/simple-hadoop-streaming-tutorial-using-joins-and-keysから見ることができるように-with-python /の場合、sortコマンドを使用してマッパーのソートを行いました。ここでは、各ループの出力を保存したり、リストや辞書にprintステートメントを保存したり、並べ替えたり、印刷して出力したりすることができます。これは単なる提案です。 – pmaniyan

+0

こんにちは@pmaniyan、応答ありがとう。私がPython、Hadoop、Mapreduceに慣れていないので、いくつかのサンプルコードを表示できますか?ありがとう、ロビー。 – Lobbie

+1

私にお試しください。ソートの問題を解決しようとしています。あなたはHadoop環境でそれを試してみる必要があります。 – pmaniyan

答えて

2

は、いくつかのコアJavaのMRとすべてを通り抜けた

おかげで、3つのファイルは、単一のマップジョブにマージすることができない、示唆しています。我々は最初の2つに最初に参加しなければならず、結果は3番目のものと結合されるべきである。あなたのロジックを3つに適用すると、良い結果が得られません。それで、私はパンダと一緒にやってみましたが、有望な結果を出すようです。 pandasを使用していない場合は、私のコードを試してみてください。そうでなければ、これらの3つのファイルをPythonの辞書とリストに結合しようとします。

私の提案するコードです。私はそれをテストするためにすべての入力を連結しました。あなたのコードでは、私のforループ(#36行目)をコメントし、forループ(line#35)をコメント解除するだけです。

import pandas as pd 
import sys 

input_string_book = [ 
"1|The Hunger Games", 
"2|To Kill a Mockingbird", 
"3|Pride and Prejudice", 
"4|Animal Farm"] 
input_string_book_df = pd.DataFrame(columns=('BookID','Title')) 


input_string_rating = [ 
"101|1|1", 
"102|2|2", 
"103|3|3", 
"104|4|4", 
"105|1|5", 
"106|2|1", 
"107|3|2", 
"108|4|3"] 
input_string_rating_df = pd.DataFrame(columns=('ReaderID','BookID','Rating')) 


input_string_reader = [ 
"101|M|1000|email", 
"102|F|1001|mobile", 
"103|M|1002|email", 
"104|F|1003|mobile", 
"105|M|1004|email", 
"106|F|1005|mobile", 
"107|M|1006|email", 
"108|F|1007|mobile"] 
input_string_reader_df = pd.DataFrame(columns=('ReaderID','Gender','PostCode','PreferComms')) 

#for line in sys.stdin: 
for line in input_string_book + input_string_rating + input_string_reader: 
    try: 

     line = line.strip() 

     splits = line.split("|") 

     if len(splits) == 2: 
      input_string_book_df = input_string_book_df.append(pd.DataFrame([[splits[0],splits[1]]],columns=('BookID','Title'))) 
     elif len(splits) == 3: 
      input_string_rating_df = input_string_rating_df.append(pd.DataFrame([[splits[0],splits[1],splits[2]]],columns=('ReaderID','BookID','Rating'))) 
     else: 
      input_string_reader_df = input_string_reader_df.append(pd.DataFrame([[splits[0],splits[1],splits[2],splits[3]]] 
      ,columns=('ReaderID','Gender','PostCode','PreferComms'))) 

    except: 
     raise 

l_concat_1 = input_string_book_df.merge(input_string_rating_df,on='BookID',how='inner') 

l_concat_2 = l_concat_1.merge(input_string_reader_df,on='ReaderID',how='inner') 

for each_iter in l_concat_2[['BookID', 'Title', 'ReaderID', 'Rating', 'Gender']].iterrows(): 
    print('%s\t%s\t%s\t%s\t%s' % (each_iter[1][0], each_iter[1][1], each_iter[1][2], each_iter[1][3], each_iter[1][4])) 

出力

1  The Hunger Games  101  1  M 
1  The Hunger Games  105  5  M 
2  To Kill a Mockingbird 102  2  F 
2  To Kill a Mockingbird 106  1  F 
3  Pride and Prejudice  103  3  M 
3  Pride and Prejudice  107  2  M 
4  Animal Farm  104  4  F 
4  Animal Farm  108  3  F 
+0

こんにちは@pmaniyan、ありがとう。私は今晩あなたのコードをここでテストします。私はまた、pd read_tableを使ってデータセットを読み込むようにコードを修正する必要があります。しかし、パンダやナンピーが許可されているかどうかは分かりませんので、数日後にあなたに戻ってきます。再度、感謝します。 – Lobbie

+0

こんにちは、悪いニュース。パンダとnumpyは許可されていないので、私はそれを難し​​い方法でやらなくてはなりません。正直なところ、これは豚や巣箱でずっと簡単です。ご協力いただきありがとうございます。よろしく、ロビー – Lobbie

+1

こんにちは@Lobbie、それは悪いニュースです。その場合は、すべての結合、A結合B、AB結合Cのコードを記述します。必要なヘルプがあれば教えてください。おかげさまで、 – pmaniyan

関連する問題