Всем привет. Извиняюсь за большой вопрос, но, пожалуйста, дочитайте до конца. Заранее спасибо.
Мое задание заключается в том что у меня есть два файла: movies.csv и rating.csv (первый на 10 000 строк, второй на 100 000 строк)
Файл movies.csv выглядит так:
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
...
Файл rating.csv выглядит так:
userId,movieId,rating,timestamp
1,1,4.0,964982703
1,3,4.0,964981247
1,6,4.0,964982224
1,47,5.0,964983815
1,50,5.0,964982931
1,70,3.0,964982400
1,101,5.0,964980868
2,110,4.0,964982176
2,151,5.0,964984041
2,157,5.0,964984100
3,163,5.0,964983650
3,216,5.0,964981208
3,223,3.0,964980985
...
В файле movies.csv содержится информация о разных фильмах, в rating.csv инофрмация о отзывах на эти фильмы.
Мне нужно на чистом питоне ( без pandas и SQL, можно пользоваться только уже встроеными функциями в python) написать консольную утилиту (определить top n наиболее рейтинговых фильмов (по средней оценке) для каждого указанного жанра), результатом будет csv-like датасет с заголовком genre, title, year, rating)
аргументы командной строки:
-N - число наиболее рейтинговых фильмов для каждого жанра. опциональный
-genres - фильтр по жанрам, задаваемый пользователем. может быть множественным. например, Comedy|Adventure или Comedy&Adventure. опциональный
-year_from
-year_to - фильтр на годы выпуска фильмов. опциональный
-regexp - фильтр (регулярное выражение) на название фильма. опциональный
если какие-то аргументы не указаны, то соответствющего фильтра нет.
если вообще ничего не указано, то выводятся все фильмы с сортировкой по жанру и среднему рейтингу (в порядке убывания)
вот то, что я написал, но это медленно работает
import argparse
import csv
parser = argparse.ArgumentParser()
parser.add_argument('-N',
type=int,
help='the number of the highest rated films for each genre'
)
parser.add_argument('-genres',
type=str,
help='filter by genre'
)
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'
)
args = parser.parse_args()
data_m = []
with open('files/movies.csv', encoding='utf-8') as file:
reader = csv.reader(file, delimiter=',')
for row in reader:
data_m.append(row)
data_movies = data_m[1:]
data_r = []
with open('files/ratings.csv', encoding='utf-8') as file:
reader = csv.reader(file, delimiter=',')
for row in reader:
data_r.append(row)
data_rating = data_r[1:]
result = [] # сюда будет добавляться средний рейтинг по фильмам
for row in data_movies:
film_ID = row[0]
sum_rating = 0.0
count = 0.0
for line in data_rating:
if film_ID == line[1]:
sum_rating += float(line[2])
count += 1
if count != 0.0:
result.append(sum_rating / count)
else:
result.append(0)
# добавление в таблицу среднего рейтинга и года
for i in range(len(data_movies)):
data_movies[i].append(result[i])
data_movies[i].append(data_movies[i][1][-5:-1])
# сейчас к data_movies добавлен средний рейтинг к каждому фильму и год выпуска фильма
# вывожу в консоль эту таблицу
for row in data_movies:
print(row)
"""
Короче, сейчас у нас есть data_movies таблица, где добавлен средний рейтинг и год к каждому фильму
!!! НО ЭТО ОЧЕНЬ МЕДЛЕННО РАБОТАЕТ
"""
Суть в том что, я сделал таблицу где есть вся информация о фильмах и добавлен средний рейтинг к каждому фильму, но чтобы получить этот средний рейтинг к каждому фильму мне пришлось вложить цикл в цикл (потому что на каждый фильм было сделано разное количество отзывов разными людьми) и там получилось около 1 миллиарда проходов, и это работает очень медленно, чтобы просто вывести эту итоговую таблицу в консоль нужно около 30 секунд.
К этой итоговой таблице я планировал применять фильтры (из аргументов командной строки) и выводить результат в консоль так, как мне показалось довольно удобным иметь готовую таблицу со средним рейтингом и просто применять к этой таблице различные условия основываясь на аргументах командной строки.
НО, ПРОСТО СДЕЛАТЬ УДОБНУЮ ТАБЛИЦУ - ОЧЕНЬ МЕДЛЕННО РАБОТАЕТ
КАКОЙ ПОДХОД ДЛЯ РЕШЕНИЯ ЭТОЙ ЗАДАЧИ ПРИМЕНИЛИ БЫ ВЫ, КАКИМ СПОСОБОМ РЕШИЛИ БЫ ЭТУ ЗАДАЧУ БЕЗ ИСПОЛЬЗОВАНИЯ СТОРОННИХ БИБЛИОТЕК?
Заранее, спасибо