今天閑來無事,發現很久之前機器上還有hadoop的安裝文件,于是來嘗試一下MapReduce的例子,順便來考驗一下自己曾經失去的python開發經驗 :(
例子是一串輸入 "a b c d a b c",所謂Map和Reduce,其實是兩個計算過程,第一個過程就是map,它用來拆分任務,羅列詳細統計結果,代碼如下:
import sys
def read_input(file):
for line in file:
yield line.split()
def main():
data = read_input(sys.stdin)
for words in data:
for word in words:
print("%s%s%d"%(word, '\t', 1)) #按照一定的格式統計每一個字符出現的次數,可以重復
if __name__ == '__main__':
main()
在python解釋器中嘗試一下
[training@localhost training_materials]$ echo "a b c d a b c" | python2.7 hdfs_map.py
a 1
b 1
c 1
d 1
a 1
b 1
c 1
于是再來討論第二個過程,reduce就是把結果分組進行匯總,得到最終的統計結果!
import sys
from operator import itemgetter
from itertools import groupby
def read_mapper_output(file, separator='\t'):
for line in file:
yield line.rstrip().split(separator, 1)
def main():
data = read_mapper_output(sys.stdin)
for current_word, group in groupby(data, itemgetter(0)): #分組統計
total_count = sum(int(count) for current_word, count in group)
print ("%s%s%d"%(current_word, '\t', total_count))
if __name__ == '__main__':
main()
再次運行來看結果吧!
[training@localhost training_materials]$ echo "a b c d a b c" | python2.7 hdfs_map.py | sort -k1,1 | python2.7 hdfs_reduce.py
a 2
b 2
c 2
d 1
順便要說一下yield的概念,這個其實是一個迭代器,用來在迭代過程之中記錄next記錄的優化方案!