Сигурен съм, че правя нещо глупаво тук, но ето го. Работя върху задание за класа за моя клас Udacity „Въведение в Map Reduce и Hadoop“. Нашата задача е да направим съпоставител/редуцент, който ще брои срещанията на дума в нашия набор от данни (тялото на публикациите във форума). Имам идея как да направя това, но не мога да накарам Python да чете stdin данни в редуктора като речник.
Ето моят подход досега: Mapper чете данните (в този случай в кода) и изхвърля речник на word:count за всяка публикация във форума:
#!/usr/bin/python
import sys
import csv
import re
from collections import Counter
def mapper():
reader = csv.reader(sys.stdin, delimiter='\t')
writer = csv.writer(sys.stdout, delimiter='\t', quotechar='"', quoting=csv.QUOTE_ALL)
for line in reader:
body = line[4]
#Counter(body)
words = re.findall(r'\w+', body.lower())
c = Counter(words)
#print c.items()
print dict(c)
test_text = """\"\"\t\"\"\t\"\"\t\"\"\t\"This is one sentence sentence\"\t\"\"
\"\"\t\"\"\t\"\"\t\"\"\t\"Also one sentence!\"\t\"\"
\"\"\t\"\"\t\"\"\t\"\"\t\"Hey!\nTwo sentences!\"\t\"\"
\"\"\t\"\"\t\"\"\t\"\"\t\"One. Two! Three?\"\t\"\"
\"\"\t\"\"\t\"\"\t\"\"\t\"One Period. Two Sentences\"\t\"\"
\"\"\t\"\"\t\"\"\t\"\"\t\"Three\nlines, one sentence\n\"\t\"\"
"""
# This function allows you to test the mapper with the provided test string
def main():
import StringIO
sys.stdin = StringIO.StringIO(test_text)
mapper()
sys.stdin = sys.__stdin__
if __name__ == "__main__":
main()
след това броят на публикациите във форума отива в stdout като: {'this': 1, 'is': 1, 'one': 1, 'sentence': 2}
тогава редукторът трябва да чете в този stdin като речник
#!/usr/bin/python
import sys
from collections import Counter, defaultdict
for line in sys.stdin.readlines():
print dict(line)
но това се проваля, като ми дава това съобщение за грешка: ValueError: dictionary update sequence element #0 has length 1; 2 is required
Което означава (ако разбирам правилно), че се чете във всеки ред не като dict, а като текстов низ. Как мога да накарам python да разбере, че редът за въвеждане е dict? Опитах да използвам Counter и defaultdict, но все още имах същия проблем или го прочетох във всеки знак като елемент от списъка, което също не е това, което искам.
В идеалния случай искам картографът да чете в dict на всеки ред, след което да добавя стойностите на следващия ред, така че след втория ред стойностите са {'this':1,'is':1,'one':2,'sentence':3,'also':1}
и така нататък.
Благодаря, JR
dict()
. Ще трябва да използвате нещо катоast.literal_eval()
, за да анализирате Python речник от низ. Или евентуално да сериализирате и десериализирате вашата структура от данни с помощта на модулаjson
. - person Lukas Graf   schedule 12.08.2014line
е стойност на един низ. - person Tritium21   schedule 12.08.2014mapper
? Това прави оригиналният код. - person nneonneo   schedule 12.08.2014