MapReduce Редуктор 2-х ключей - Python - PullRequest
       35

MapReduce Редуктор 2-х ключей - Python

0 голосов
/ 21 сентября 2018

Это должно быть довольно просто, и я потратил на это несколько часов.

Пример данных (имя, двоичный код, количество):

Adam 0 1
Adam 1 1
Adam 0 1
Mike 1 1
Mike 0 1
Mike 1 1  

Требуемый пример Выход (имя, двоичный код, количество):

Adam 0 2
Adam 1 1
Mike 0 1
Mike 1 2  

Каждое имя должно иметьего собственный двоичный ключ 0 или 1. На основе двоичного ключа, суммируйте столбец count.Обратите внимание на «уменьшение» в желаемом выходе.

Я предоставил часть своего кода и пытаюсь обойтись без списков или словаря в редукторе.

"" "Редуктор принимает имена со своими двоичными и частичнымиcount добавляет их до

Ввод: имя \ t двоичный файл \ t pCount

Выход: имя \ t бинарный \ t tCount
"" "

import re
import sys

current_name = None
zero_count, one_count = 0,0

for line in sys.stdin:
    # parse the input
    name, binary, count = line.split('\t')

   if name == current_name:
      if int(binary) == 0:
        zero_count += int(count)

    elif int(binary) == 1:
        one_count += int(count)
else:
    if current_name:
        print(f'{current_name}\t{0} \t{zero_count}')
        print(f'{current_name}\t{1} \t{one_count}')
    current_name, binary, count = word, int(binary), int(count)

print(f'{current_name}\t{1} \t{count}')

Дляпо какой-то причине, он не печатает должным образом.(первое имя, которое проходит через это фанки) Я также не уверен, что лучший способ пройти через все печати для one_count и zero_count, который также отображает свои двоичные метки.

Любая помощь будет принята с благодарностью.Спасибо!

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Отступ был плохим, и условия не были обработаны должным образом.

import re
import sys

current_name = None
zero_count, one_count = 0,0
i = 0
for line in sys.stdin:
    # parse the input
    name, binary, count = line.split('\t')
    #print(name)
    #print(current_name)
    if(i == 0):
        current_name = name
        i  = i + 1
    if(name == current_name):
        if int(binary) == 0:
            zero_count += int(count)

        elif int(binary) == 1:
            one_count += int(count)
    else:
        print(f'{current_name}\t{0} \t{zero_count}')
        print(f'{current_name}\t{1} \t{one_count}')
        current_name = name
        #print(current_name)
        zero_count, one_count = 0,0
        if int(binary) == 0:
            zero_count += int(count)
        elif int(binary) == 1:
            one_count += int(count)
print(f'{current_name}\t{0} \t{zero_count}')
print(f'{current_name}\t{1} \t{one_count}')

'i' обрабатывает случай, когда у вас нет 'current_name' для первой строки ввода (он будет запущентолько один раз).
В блоке else вы должны были повторно инициализировать 'zero_count' и 'one_count', а также выполнить расчет для нового 'current_name'.

Вывод для моего кода:

Adam    0       2
Adam    1       1
Mike    0       1
Mike    1       2
0 голосов
/ 21 сентября 2018

Я думаю, что лучше всего использовать библиотеку панд.

import pandas as pd
from io import StringIO
a ="""Adam 0 1
Adam 1 1
Adam 0 1
Mike 1 1
Mike 0 1
Mike 1 1"""

text = StringIO(a)
name, binary, count = [],[],[]

for line in text.readlines():
    a = line.strip().split(" ")
    name.append(a[0])
    binary.append(a[1])
    count.append(a[2])

df = pd.DataFrame({'name': name, "binary": binary, "count": count})
df['count'] = df['count'].astype(int)
df = df.groupby(['name', 'binary'])['count'].sum().reset_index()
print(df)
name    binary  count
0   Adam    0   2
1   Adam    1   1
2   Mike    0   1
3   Mike    1   2

, если ваши данные уже в CSV или текстовом файле.Его можно прочитать с помощью панд.

df = pd.read_csv('path to your file')
...