Суть задания, которое я делаю:
Есть файл movies.csv (на 10 000 строк), кстати, если это имеет значение то вы можете его скачать таки образом: wget
https://files.grouplens.org/datasets/movielens/ml-...
файл выглядит так:
movieId,title,genres
1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fantasy
2,Jumanji (1995),Adventure|Children|Fantasy
3,Grumpier Old Men (1995),Comedy|Romance
4,Waiting to Exhale (1995),Comedy|Drama|Romance
5,Father of the Bride Part II (1995),Comedy
6,Heat (1995),Action|Crime|Thriller
7,Sabrina (1995),Comedy|Romance
8,Tom and Huck (1995),Adventure|Children
9,Sudden Death (1995),Action
...
Сейчас, с помощью подхода mapreduce мне нужно, чтобы файл, который называется mapper.py, выводил в консоль ключи и значения, где ключ это жанр фильма, а значение это название фильма и его год, при этом должна быть возможность фильтровать фильмы по названию, году и жанру по аргументом командной строки, а если мы не передаем эти аргументы, то должны выводится в консоль все фильмы.
Пример:
есть такая строка:
1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fantasy
как видно, у нее несколько жанров, а в консоли mapper.py должен печатать этот фильм так:
Adventure Toy Story;1995
Animation Toy Story;1995
Children Toy Story;1995
Comedy Toy Story;1995
Fantasy Toy Story;1995
ну и так далее по всем фильмам
запускаю это я таким образом: cat files/movies.csv | python3 mapper.py [здесь можно передавать аргументы для фильтрации фильмов по желанию]
мой файл mapper.py выглядит так:
import sys
import argparse
import re
def argpars():
parser = argparse.ArgumentParser()
parser.add_argument('-genres',
type=str,
help='filter by genre',
default=''
)
parser.add_argument('-year_from',
type=int,
help='filter by year (FROM YEAR)',
default=1800
)
parser.add_argument('-year_to',
type=int,
help='filter by year (TO YEAR)',
default=2025
)
parser.add_argument('-regexp',
type=str,
help='filter on the movie name',
default=''
)
return parser.parse_args()
def print_result(data, year_from, year_to, name, genres_argument):
for line in data:
for key, value in map(line, year_from, year_to, name, genres_argument):
print(key, "\t", str(value))
def map(line, year_from, year_to, name, genres_argument):
list_line = line.split(",")
list_line[2] = list_line[2][:-2]
# filter by year and regexp
if filter_by_year(year_from, year_to, list_line[1]) and filter_by_regexp(name, list_line[1]):
# filter by genres
list_genres_argument = genres_argument.split('|')
genres = list_line[2].split('|')
for arg_genre in list_genres_argument:
for genre in genres:
if filter_by_genres(genre, arg_genre):
key = genre
value = '{};{}'.format(list_line[1][:-7], list_line[1][-5:-1])
yield key, value
def filter_by_year(year_from, year_to, string):
pattern = r'\(\d{4}\)'
if re.search(pattern, string):
year = re.search(pattern, string)
a = year.group(0)[1:-1]
int_year = int(a)
if year_from <= int_year <= year_to:
return True
def filter_by_regexp(name, string):
pattern = name
if re.search(pattern, string):
return True
def filter_by_genres(genre, genres_argument):
if genres_argument == '' and genre != '(no genres listed)':
return True
elif genre == genres_argument and genre != '(no genres listed)':
return True
if __name__ == "__main__":
args = argpars()
print_result(sys.stdin, args.year_from, args.year_to, args.regexp, args.genres)
Этот код полностью рабочий и выполняет свою задачу правильно ( он выводит в консоль ключ и значение, где ключ это жанр, а значение это строка название_фильма;год). Но с точки зрения mapreduce здесь функция map реализована не совсем верно, хотя этот файл полностью справляется со своей задачей. Как изменить это, чтобы это выглядело более правильно? Да и вообще буду рад увидеть любой комментарий по этому коду (например: как лучше назвать функцию или переменную, кстати да, реально, может поменять названия некоторых функций, чтобы был более читабельный код? )
Но функция map должна быть, и как ее реализовать правильным образом, чтобы это полностью соответствовало подходу mapreduce? Может вообще нужно поменять структуру кода?
Что должна делать функция map в рамках моей задачи
ЧТО ДОЛЖНА ДЕЛАТЬ ФУНКЦИЯ map() в рамках моей задачи, что она должна принимать на вход, что должна возвращать?