Когда я впервые начал работать специалистом по данным (или что-то в этом роде), мне сказали программировать на C++ и Java. Затем появился R, и это освободило; моя способность проводить анализ данных существенно возросла. По мере роста размера и сложности моих приложений я начал скучать по структуре Java/C++. В то время Python казался хорошим компромиссом, поэтому я снова переключился. После прихода в Mango Solutions я заметил, что не являюсь аномалией, большинство специалистов по данным здесь знают и Python, и R.
В настоящее время всякий раз, когда я делаю свою работу в R, в моей голове постоянно звучит ворчливый голос, говорящий мне: «Вы должны сделать это в Python». И когда я делаю свою работу на Python, он говорит мне: «Вы можете сделать это быстрее в R». Поэтому, когда вышла упаковка reticulate, я был вне себя от радости, и в этом посте я объясню вам, почему.
ре-тик-у-поздно (rĭ-tĭkˈyə-lĭt, -latˌ)
Так что же именно делает reticulate? Его цель — облегчить взаимодействие между Python и R. Он делает это, встраивая сеанс Python в сеанс R, что позволяет вам вызывать функции Python из R. Я не собираюсь вдаваться в подробности того, как пакет работает здесь; RStudio проделала большую работу, предоставив прекрасную документацию и веб-семинар. Вместо этого я покажу несколько примеров основного функционала.
Как и R, House of Python был построен на пакетах. За исключением Python, вы не загружаете функциональность из пакета через вызов library
, а вместо этого импортируете модуль. reticulate имитирует это поведение и открывает все преимущества импортированного модуля.
library(reticulate) np <- import("numpy") # the Kronecker product is my favourite matrix operation np$kron(c(1,2,3), c(4,5,6))
## [1] 4 5 6 8 10 12 12 15 18
В приведенном выше коде я импортирую модуль numpy, который является мощным пакетом для всех видов числовых вычислений. Затем reticulate дает нам интерфейс ко всем функциям (и объектам) из модуля numpy. Я могу вызывать эти функции точно так же, как и любую другую функцию R, и передавать объекты R, reticulate позаботится о том, чтобы объекты R были преобразованы в соответствующие объекты Python.
Вы также можете запустить код Python через source_python
, если это весь скрипт, или py_eval
/py_run_string
, если это одна строка кода. Любые объекты (функции или данные), созданные скриптом, загружаются в вашу среду R. Ниже приведен пример использования py_eval
.
data("mtcars") py_eval("r.mtcars.sum(axis=0)")
## mpg 642.900 ## cyl 198.000 ## disp 7383.100 ## hp 4694.000 ## drat 115.090 ## wt 102.952 ## qsec 571.160 ## vs 14.000 ## am 13.000 ## gear 118.000 ## carb 90.000 ## dtype: float64
Обратите внимание на использование префикса r.
перед объектом mtcars
в коде Python. Объект r
предоставляет среду R для сеанса Python, его эквивалентом в сеансе R является объект py
. mtcars
data.frame преобразуется в pandas DataFrame, к которому я затем применяю функцию sum
для каждого столбца.
Очевидно, что RStudio приложила много усилий, чтобы обеспечить плавный интерфейс с Python, от простого преобразования объектов до интеграции с IDE. reticulate не только позволит пользователям R извлечь выгоду из множества функциональных возможностей Python, я полагаю, что это также обеспечит более тесное сотрудничество и более широкий обмен знаниями.
Введите почтальон
Так что же именно вы можете сделать с Python, чего не можете с R? Я задавал себе тот же вопрос, пока не наткнулся на следующий вариант использования.
Когда я помогал коллеге с записью в блоге, мне предложили опубликовать ее во вторник. Никакого обоснования не было дано, поэтому, естественно, я задался вопросом, могу ли я предоставить его, используя данные. Данные должны поступать от R-блогеров. Это отличный ресурс для чтения сообщений в блогах о R (и связанных темах), а также они предоставляют ежедневный информационный бюллетень со ссылкой на сообщения в блоге за тот день. В то время новостная рассылка казалась самым простым способом сбора данных 1. Все, что мне нужно было сделать сейчас, это извлечь данные из моей учетной записи Gmail.
В этом и заключается проблема, так как я хочу избежать запросов к серверу Gmail (это не упростит воспроизведение). К счастью, Google упростил загрузку ваших данных (благодаря Фронту освобождения данных Google) через Google Архиватор. К сожалению, все электронные письма экспортируются в формате mbox. Хотя это обычный текстовый формат, для написания синтаксического анализатора на R потребуются некоторые усилия, чего я не хотел делать. А затем появился Python со встроенным парсером mbox в модуле mailbox.
Используя reticulate, я извлек необходимую информацию из каждого электронного письма.
# import the module mailbox <- import("mailbox") # use the mbox function to open a file connection cnx <- mailbox$mbox("rblogs_box.mbox")
# the messages are stored as key/value pairs # in this case they are indexed by an integer id message <- cnx$get_message(10L) # each message has a number of fields with meta-data message$get("Date")
## [1] "Mon, 12 Dec 2016 23:56:19 +0000"
message$get("Subject")
## [1] "[R-bloggers] Building Shiny App exercises part 1 (and 7 more aRticles)"
И вот оно! Я только что прочитал электронное письмо из файла mbox без особых усилий. Конечно, мне нужно будет сделать это для всех сообщений, поэтому я написал функцию, которая мне поможет. И поскольку мы живем в эпоху R, я поместил эту функцию в пакет R. Вы можете найти его в репозитории MangoTheCat на github, он называется mailman.
Публиковать или не публиковать?
Мне еще предстоит обосновать публикацию сообщения в блоге в определенный день, поэтому давайте быстро перейдем к нему. Теперь, когда пакет отсортирован, я могу вызвать функцию mailman::read_messages
, чтобы получить tibble
со всем, что мне нужно.
Мы можем извлечь количество сообщений в блоге на определенную дату из темы каждого электронного письма. Объединение этого с днем недели даст нам хорошее представление о том, какой день популярен.
library(dplyr) library(mailman) library(lubridate) library(stringr)
messages <- read_messages("rblogs_box.mbox", type="mbox") %>% mutate(Date = as.POSIXct(Date, format="%a, %d %b %Y %H:%M:%S %z"), Day_of_Week = wday(Date, label=TRUE, abbr=TRUE), Number_Articles = str_extract(Subject, "[0-9](?=[\\n]* more aRticles)"), # Whenever a regex works you feel like a superhero! Number_Articles = as.numeric(Number_Articles) + 1, # Ok, sometimes it doesn't work but you're still a hero for trying! Number_Articles = ifelse(is.na(Number_Articles), 1, Number_Articles)) %>% select(Date, Day_of_Week, Number_Articles)
Судя по графику, выходные — хорошее время для публикации поста в блоге, так как конкуренция меньше. С другой стороны, не многие люди могут читать сообщения в блогах на выходных. Следующим кандидатом будет понедельник, который имеет самый низкий средний показатель среди будних дней. Возвращаясь к своему первоначальному заданию, могу сделать вывод, что публикация во вторник — не лучший вариант.
В итоге
На мой взгляд, пакет reticulate — это новаторская разработка. Это позволяет мне сочетать хорошие части R с хорошими частями Python (он уже используется в пакетах tensorflow и keras). Кроме того, это позволяет сообществу специалистов по данным легче сотрудничать и направлять нашу энергию на выполнение задач. Это будущее, это R и Python (Rython? PRython? PyR?).
- После того, как я собрал все данные, Боб Рудис написал об API Feedly и опубликовал набор сообщений в блогах за более длительный период времени. Я бы сказал, что его решение предпочтительнее, хотя мои результаты немного отличаются из-за более позднего временного горизонта.
Читайте другие статьи о науке о данных на OpenDataScience.com