Краткий обзор: в прошлом месяце я закончил Чикагский проект Python, успешно найдя и извлек данные статистики MLB, успешно загрузив и установив MongoDB, а также запланировав, когда будет происходить поиск моих данных!
Тем не менее, пара вещей была пропущена. В моей функции для загрузки данных статкаста был довольно длинный список жесткого кода, который конвертировал бы определенные переменные в числовые данные. С тех пор это было исправлено в обновленной функции, где я использую список, содержащий имена переменных, и функцию применения для приведения к числовому значению. То, что когда-то занимало более двадцати строк, теперь имеет место с одним списком в файле конфигурации и одной функцией применения, теперь это то, что я называю улучшением.
Теперь о том, что будет происходить на этой неделе в выпуске… Итак, вы хотите выучить Python. На этот раз я приступил к написанию функций для перемещения моих данных в мою базу данных MongoDB, запросов к моей базе данных и использования Altair для создания точечной диаграммы, отображающей местоположения полей. К сожалению, у меня не хватило времени написать функцию для сбора фанграфов, однако мне удалось использовать Beautiful Soup 4.4 для сбора дополнительных данных. Тем не менее, на этой неделе я меняю формат с попытки описать то, что я сделал, за которым следует код, на более подробное объяснение, чтобы я мог вернуться к этому сообщению, когда я, несомненно, забуду, как выполнять запись какой-либо функции, запрашивать MongoDB или как для создания графика Альтаира.
Написание функций Python
Предупреждение: далее следует краткое описание функций, за которым следует код, который не является полным, но значительно лучше того, что у меня было раньше… который не был функциями.
Функции — это волшебные фрагменты кода, которые улучшают читабельность и помогают разделить работу на полезные фрагменты. Функции Python состоят из заголовка блока, ключевого слова блока и аргумента(ов).
def function_name(argument1, argument2, etc):
В python заголовок блока — def, а ключевое слово block_keyword — это имя функции. Переменная может быть передана в функцию, и функция может даже вернуть значение... вау, это круто. Я хотел бы воспользоваться моментом, чтобы поблагодарить Ларри Пейджа и Сергея Брина, без этих двоих я был бы отправлен в библиотеку, просматривая тома текста, чтобы узнать, что заняло минуты в Google. Теперь вернемся к действию… чтобы вызвать функцию, все, что нужно сделать пользователю, это ввести имя функции и передать необходимые аргументы.
У каждого языка свой синтаксис. Например, я могу написать функцию в SAS, набрав следующее:
%macro <macro name>(<macro variable(s)); <macro code> %mend;
Или я мог бы написать функцию в R, написав:
<function name> <- function(<function variable>) { < function code > return(my_list) }
По мере того, как я писал и начинал больше использовать функции, у меня возникла мысль, а вдруг кто-то воспользуется функцией неправильно и получит ошибку. Можно ли написать собственное сообщение об ошибке? В этот момент на помощь пришел мой наставник и направил меня по пути использования блока try и except для пользовательских сообщений об ошибках. После быстрого поиска в Google, еще раз спасибо Ларри и Сергею, я нашел прекрасную ссылку (https://realpython.com/python-exceptions/), где я узнал немного больше, чем то, что мой наставник сказал мне во время нашего еженедельного встречи. В статье были рассмотрены различия между исключениями и синтаксическими ошибками, возбуждение исключения, блок try и exclude, а также включение предложения else в блок try и exclude. Рекомендую прочитать статью, если есть возможность.
Вооружившись моими недавно полученными знаниями, я написал функцию для перемещения данных в мою базу данных и для создания точечной диаграммы, показывающей расположение шагов и сгруппированной по типу шагов.
Altair — замечательная библиотека, которую мне порекомендовал мой наставник. Он отвечает за диаграмму местоположения поля и очень похож на ggplot2 в R. Кроме того, он был создан Джейком ВандерПласом, который очень помог с stackoverflow и ответил на мой вопрос о том, как включить поле для представления зоны удара. До сих пор Altair — это моя библиотека для визуализации данных в Python. Ниже вы можете найти мой код для создания приведенного выше графика с блоками try и except в качестве универсального. Это область, к которой мне нужно будет вернуться и пересмотреть мою пользовательскую обработку ошибок.
Использование красивого супа
Когда я просматривал свои текущие данные, я понял, что для достижения моей цели использования дерева решений для прогнозирования ежедневных очков фантазии для конкретного игрока мне потребуется другое представление данных, поскольку мое текущее представление было очень гранулированным. Итак, я направился на мой любимый бейсбольный сайт fangraphs! У них там все есть, сводная статистика, новые саберметрики, это рог изобилия информации. Но как бы я его получил? Вот где в игру вступает Beautiful Soup. Изучив веб-страницу, я увидел структуру, организованную по тегам, и подумал, что Beautiful Soup идеально подойдет для этого. Изучив их политику robots.txt, я увидел, что они разрешают парсинг, и начал изучать новый набор навыков.
Примерно через час безуспешных проб и ошибок я понял, что эта часть будет сложной. Итак, я сделал то, что сделал бы любой предприимчивый человек, который хотел бы сократить свою кривую обучения, я провел некоторые исследования и разработки, также известные как поиск, чтобы узнать, сделал ли это кто-то еще, и манипулировать их кодом для моих нужд. К счастью, у кого-то было… спасибо, conorkcobin, без вашего гитхаба это было бы сложнее
Теперь, когда у меня есть солидная база исследований и разработок, я начал собирать данные о Майке Трауте.
Запрос MongoDB через pyMongo
После перезагрузки компьютера я долго не мог подключиться к своей MongoDB через pyMongo… что дает?! Ну, так как я новичок, я совершенно упустил из виду тот факт, что мне нужно было запустить свою базу данных. Быстрый поиск в Google привел меня к выводу, что мне нужно выполнить следующее.
"C:\Program Files\MongoDB\Server\4.0\bin\mongod.exe"
После успешного запуска базы данных и подключения к ней через pyMongo я мог приступить к выполнению запроса к базе данных. Зная, что коллекция состоит из документов, а эти документы эквивалентны записи в базе данных SQL, я начал структурировать свой запрос на более знакомом языке. Я знал, что хочу выбрать все столбцы из моей коллекции pitch_level и, чтобы ограничить свои результаты, я выберу только документы из одной игры, где game_pk = 529412. Что обычно выглядело бы примерно так из
SELECT * FROM pitch_level WHERE game_pk = 529412
Более кратко можно было бы написать так:
results_df = mydb.mycol.find({"game_pk" : 529412})
В приведенном выше коде я не смог вернуть запрос на основе значения уникального идентификатора игры, но я смог сохранить результаты в кадре данных pandas! Разговор о легком!
Но что, если я хочу найти документы, которые имеют значение БОЛЬШЕ или МЕНЬШЕ определенного значения? Что ж, в mongoDB это так же просто, как
mydb.mycol.find{<column> : {"$gt" : <value>}} mydb.mycol.find{<column> : {"$lt" : <value>}}
Как говорит мой любимый магазин канцтоваров, «это было легко». Но что, если я хочу вернуть результаты, находящиеся между двумя? Ни слова больше, все, что нужно сделать, это:
# Between 2 dates my_db.my_collection.find({"<column>": {"$gte": <value1>, "$lt": <value2>}})
Но что, если я хочу найти документ либо с этим значением, либо с этим значением? Не говорите больше, потому что pyMongo поможет вам:
my_db.my_collection.find({"$or":[{"<column>":<value1>},{"<column>":"<value2>"}]})
Как насчет того, чтобы найти документ со значениями в определенной группе? В PyMongo это тоже есть:
my_db.my_collection.find({"<column>":{"$in":[<value1>,<value2>]}})
Как насчет того, чтобы найти документ, которого нет в определенной группе. Да, в pyMongo это тоже есть:
my_db.my_collection.find({"<column>":{"$nin":[<value1>,<value2>]}})
Объединив мои новые знания в области запросов и написания функций, я смог составить общую функцию запросов:
Следующие шаги
Проект определенно продвигается вперед, но есть пара критических моментов, которые необходимо решить. Мне нужно очистить функцию, которая перемещает данные в mongoDB. В настоящее время я переименовываю столбцы в функции, и об очистке данных нужно заботиться вне функции или в другой функции. Мне также нужно поместить парсер фанграфов в функцию и определить методологию парсинга только определенных игроков, которые играли в игру в день, когда функция запускается автоматически. Мне также нужно лучше реализовать пользовательские сообщения об ошибках в functions. Затем я могу начать искать способы предсказывать ежедневные очки фантазии. Кроме того, мне нужно потратить немного больше времени на создание двумерного графика плотности, показывающего вероятность того, что шаг будет назван ударом, учитывая, где он пересекает плиту. Эта вероятность была рассчитана с помощью общей аддитивной модели. Кроме того, это полезно, когда нужно посмотреть, получал ли питчер благоприятные звонки или, возможно, кэтчер хорош в кадрировании подачи. Однако это будет бесполезно, если не будет способа передать весь мой анализ. Таким образом, flask придется закодировать, чтобы показать графики, которые будут передавать всю эту информацию. Я надеюсь, что вы присоединитесь к нам на следующей неделе в «Боже мой, так много работы осталось сделать!!!!».