Почему мы учим Pandas вместо SQL?
21 мая 2022 г.Фото Педро Гонсалеса на Unsplash
Жил-был студент, который очень хотел изучать науку о данных.
Он спрашивал людей, что ему делать, и они говорили ему изучать панд. Он искал в Интернете курсы по работе с данными, и все они были посвящены пандам. Итак, студент выучил панд, а затем устроился на работу в академию, где все работали с пандами.
Поэтому он мучился с пандами много лун, пока не научился нарезать датафреймы во сне. Когда он закончил, он присоединился к буткемпу данных: о чудо, они обучали панд. Когда он закончил, буткемп нанял его — обучать панд.
- Затем настало время, когда студент поступил в свою первую компанию. Его хозяин хотел, чтобы он обработал некоторые данные.*
- «Я буду использовать панд», — сказал студент.*
- «Черт возьми!» сказал мастер. «Здесь мы используем S—Q—L», — возразил он, подчеркивая каждую букву ударом палки*.
«Но... Но... Многословие... Уродство... Отсутствие функций... Бесконечная вложенность... А джойны, джойны ужасны!...»
- «Если не видишь леса, то и деревьев не трогай», — сказал мастер, ударив его по голове.*
Студент был просветлен.
Или так он думал; на самом деле удар мастера так сильно оглушил его, что его рассудок временно помутился.
- Много месяцев спустя, после болезненного отказа, студент понял SQL. С тех пор он больше не чувствовал необходимости использовать панд, и мастер больше никогда не наносил ему ударов.*
SQL >> Панды
Приведенный выше коан автобиографичен, хотя я должен отметить, что ни один из моих начальников никогда не бил меня (даже когда должен был).
С тех пор, как я начал, мало что изменилось. Учебные программы большинства учебных курсов по работе с данными предусматривают значительные инвестиции в панды (наряду с блокнотами Jupyter), в то время как SQL в лучшем случае рассматривается задним числом.
Поищите в Udemy слово «наука о данных», и вы увидите лучшие курсы, в которых упоминается Python (который неизбежно включает pandas) и R, а иногда даже Scala. Очень немногие из них упоминают SQL.
Я считаю, что это плохо и с ценностной точки зрения, и с педагогической.
Проблема ценности
Если вы занимаетесь стандартной аналитикой, SQL просто лучше, чем pandas. Это проще, понятнее, мощнее и эффективнее. Его также легче понять, поделиться и воспроизвести. Есть причина, по которой на протяжении десятилетий это был лингва-франка аналитики данных.
Если вы сосредотачиваетесь на Pandas в ущерб SQL, вы упускаете возможность стать лучшим и более эффективным специалистом по данным.
Конечно, есть вещи, которые панды делают лучше, и я кратко расскажу о них в конце статьи. Но в целом, когда дело доходит до чистой аналитики, SQL сложно превзойти.
Люди часто не замечают, что панды вносят значительные накладные расходы с точки зрения сложности, неэффективности, идиосинкразии и возможностей для путаницы.
Проблема обучения
Я подозреваю, что чрезмерный акцент на пандах вредит студентам, изучающим данные. По моему опыту, есть момент, когда большее количество панд приводит к анти-обучению, т.е. человек просто становится более запутанным с течением времени.
Новые ученики, в частности, сталкиваются со странными проблемами, которые их смущают и которые они компенсируют слепым запоминанием.
Они также приобретают вредные привычки, от которых потом трудно отказаться, например, перебирать строки в цикле, когда они могут использовать операции с таблицами; создание столбцов со смешанными типами; сохранение данных в CSV; изменение данных на месте; засорение памяти несколькими копиями и фрагментами одного и того же фрейма данных... Я мог бы продолжить.
Частично это связано с тем, что Python является чрезвычайно терпимым языком, который возлагает на пользователя бремя не делать плохих вещей (например, «серии» панд со смешанными типами). Частично это происходит из-за того, что панды принимают (хотя и не обязательно поощряют) императивный подход.
Например, если студент хочет объединить данные из двух таблиц, ничто не мешает ему использовать этот алгоритм:
- Зациклиться на
table1
- Для каждой строки
table1
просканируйте всюtable2
для поиска
- Обновите строку в
table1
из данных вtable2
Да, это явно очень плохо. Но новички не знают ничего лучшего.
Напротив, декларативный подход SQL затрудняет выполнение плохих действий.
Декларативное программирование заставляет пользователя думать с точки зрения результата, который он хочет увидеть, а не о том, как его получить. Это дает им пространство, необходимое им, чтобы сосредоточиться на логике, лежащей в основе их анализа, вместо того, чтобы постоянно увязнуть в проблемах и странных ошибках.
SQL также заставляет студентов думать в таблицах (т. е. реляционная модель) и операциях на уровне столбцов, что очень полезно, когда их первое побуждение - перебрать все в цикле.
Наконец, изучение SQL дает большую отдачу от инвестиций благодаря его универсальности и переносимости.
Отказ от ответственности
Я не ненавижу панд. Это был мой основной аналитический инструмент в течение двух лет, и я до сих пор использую его для своих личных проектов. Я рад, что люди учатся этому.
Но я пытаюсь увидеть более широкую картину. Я думаю, что чрезмерное выделение панд за счет SQL приносит больше вреда, чем пользы. Особенно, когда речь идет о новичках, которые узнают о «MultiIndex» панд, прежде чем они смогут правильно выполнить «GROUP BY».
Перспектива
В следующем разделе я проанализирую некоторые из самых странных аспектов панд и сравню их напрямую с SQL.
Цель, опять же, состоит не в том, чтобы подавить панд, а в том, чтобы расширить представление читателя об имеющихся в его распоряжении инструментах.
Давайте углубимся.
```sql
ВЫБРАТЬ *
ОТ самоуверенного_сравнения
ГДЕ sql > панды
Сравнение
Выбор столбцов
В одном операторе SQL SELECT
позволяет вам:
- Выберите нужные столбцы и порядок их возврата.
- Создайте новые столбцы на основе комбинаций и преобразований существующих столбцов.
- Переименуйте столбцы.
В этом примере выбираются все столбцы, кроме одного, затем создается новый столбец на основе линейной комбинации двух других столбцов:
```sql
ВЫБЕРИТЕ * ЗА ИСКЛЮЧЕНИЕМ (first_name),
Equity_Comp / Total_Comp * 100 AS процент_эквити
ОТ зарплаты
Выбор столбца pandas позволяет выбирать и упорядочивать столбцы. Если вы хотите переименовать или преобразовать некоторые из них, вам потребуется несколько операторов, и многие люди ошибаются при преобразовании данных на месте (см. неизменность ниже).
Новички путаются, потому что для выбора одного столбца требуется один набор скобок (df["first_name"]
), а для выбора нескольких столбцов требуется двойной набор скобок (df[["first_name", "last_name"]]
).
Самая большая проблема, с которой я столкнулся с пандами, — это запись через точку: тот факт, что вы можете выбирать такие столбцы: df.first_name
.
Это намного проще, чем использовать скобки и кавычки, поэтому люди в конечном итоге предпочитают это просто из-за лени. По крайней мере, так случилось со мной: я до сих пор автоматически использую запись через точку, хотя и знаю, что это плохо.
Проблемы возникают, когда у вас есть столбец с именем count
, shape
, diff
или любой другой из многих стандартных атрибутов фрейма данных (вы можете увидеть их все с помощью dir(df)
).
Когда вы попытаетесь получить к ним доступ с помощью записи через точку, вы получите атрибут вместо столбца, и ваш код сломается.
Таким образом, у pandas есть три способа выбора столбцов: два для получения одного столбца (из которых один плохой, но более привлекательный!) и третий для выбора нескольких столбцов.
Выбор строк
В SQL для выбора определенных строк вы просто используете оператор WHERE (см. раздел «Фильтрация» ниже).
Выбор строк в Pandas... сложен. Чтобы узнать, насколько это сложно, ознакомьтесь с начальным руководством пользователя. Или изучите типичное 30-минутное руководство.
Я ограничусь одним примером. Каждый DataFrame имеет «Индекс». Индекс по умолчанию представляет собой последовательность целых чисел: [0,1,2,3,4,5...]
.
Естественно, большинство людей предполагает, что индекс представляет мощность строк. На самом деле цифры — это просто категориальные ярлыки! С таким же успехом это могут быть случайные буквы, такие как ['x', 'z', 'a']
. Кардинальность не подразумевается.
Чтобы получить строку по ее индексу, вы используете df.loc
. Но для выбора по кардинальности строки вы используете df.iloc
. С индексом по умолчанию эти два метода дают одинаковый результат.
Что только добавляет путаницы, потому что в любой момент ваш индекс может измениться на что-то совершенно случайное, например [7, 2, 2, 'c', True, None]
. Да, все это разрешено! И нет никаких ограничений, чтобы предотвратить это (см. Ограничения ниже).
Представьте, что вы написали свой код, предполагая, что индекс представляет мощность строки. Теперь:
df.loc[7]
вернет первую строку
df.loc[2]
вернет фрагмент кадра данных вместо строки (поскольку он встречается в индексе более одного раза)
df.loc[None]
вернет реальную строку!
Я не плачу, ты плачешь.
И да: один и тот же метод может возвращать скалярное значение, строку или срез данных в зависимости от того, как составлен индекс. Документы панд признают это безумие:
Другие методы, такие как индексация, могут дать очень неожиданные результаты. Обычно индексирование со скаляром уменьшает размерность. Разделение DataFrame с помощью скаляра вернет серию. Разделение серии с помощью скаляра вернет скаляр. Но с дубликатами [index] дело обстоит иначе.
И помните, что нет никаких ограничений, препятствующих тому, чтобы индекс содержал дубликаты. Я не могу начать рассказывать вам, сколько головной боли это вызвало у меня.
(Помимо всех методов выбора, которые мы упомянули, в pandas также есть df.at
и df.iat
для одиночных значений. Еще одна вещь, о которой нужно помнить, чтобы не запутаться.)
Фильтрация
В SQL фильтрация проста. Напишите WHERE
, вставьте столько утверждений, сколько хотите, и соедините их логическими операторами. Скобки дают вам больше контроля над структурированием выражений.
Например, следующие запросы фильтруют людей, которым больше 30 лет и которые удовлетворяют хотя бы одному из двух условий: стаж работы более 5 лет или компенсация долевого участия менее 50:
```sql
ВЫБРАТЬ *
от зарплаты
ГДЕ возраст > 30 И (должность > 5 ИЛИ equity_comp < 50)
Как это выглядит в пандах?
```питон
new_df = df[(df["age"] > 30) & ((df["tenure"] > 5) | (df["equity_comp"] < 50))]
Фу. Повеселитесь, объясняя это новичкам.
Конечно, вы, вероятно, не написали бы это так, потому что это слишком уродливо. Вы бы выполнили фильтрацию в нескольких операторах: это означает больше строк кода, переменных и повторений.
Фильтры Pandas основаны на методе, называемом [логическое индексирование] (https://pandas.pydata.org/docs/user_guide/10min.html#boolean-indexing). Каждая операция фильтрации происходит в два этапа:
- Вы берете «Серию» (это объект столбца) и запускаете каждый элемент через логический тест. Таким образом, преобразуя его в новую «Серию», состоящую из логических значений (true или false).
- Вы выбираете фрейм данных с этим столбцом, который в конечном итоге исключает строки, в которых логическое значение «Серия» содержит ложное значение.
Заметили здесь скрытое предположение? «Серия», используемая для фильтрации, и фильтруемый фрейм данных должны иметь один и тот же индекс в одном и том же порядке. Это не всегда гарантируется.
На практике логическое индексирование означает, что при фильтрации вам всегда нужно повторять переменную фрейма данных, например. зарплаты[зарплаты["cash_comp"] > 20]
. Это очень раздражает, когда вы пишете много кода! См. пример выше: на переменную dataframe ссылаются 4 раза.
Я также могу сказать по своему опыту, что логическое индексирование не так просто понять новичкам. Некоторые люди вообще никогда не понимают лежащего в основе механизма. Они просто запоминают шаблон кодирования.
(Похоже, что метод df.query()
обеспечивает [лучший метод фильтрации] (https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html).)
Группировка
Здесь нет серьезных претензий. Но SQL определенно ближе к английскому языку. Эти два эквивалентны:
```sql
ВЫБЕРИТЕ AVG(cash_comp), SUM(должность)
ОТ зарплаты
СГРУППИРОВАТЬ ПО отделам
```питон
grouped_df = df.groupby('отдел').agg({"cash_comp": np.mean, "tenure": np.sum})
Присоединяется
SQL имеет один тип соединения. Это называется «ПРИСОЕДИНЯЙСЯ». Конечно, он может быть левым/правым и внутренним/внешним, но использовать его довольно просто.
В Pandas есть два метода: «присоединиться» и «слить». Никогда не понимал, зачем нам два. Предполагается, что join
работает с индексами, merge
должен работать с любым столбцом.
Но если вы посмотрите документы [1][2] каждый из них поддерживает как индексы, так и столбцы. Я в замешательстве. (Если вы сомневаетесь, я бы посоветовал всегда выбирать «слияние», поскольку «объединение» — это скорее устаревший метод.)
SQL действительно упрощает ПРИСОЕДИНЕНИЕ на основе цепочки логических условий, таких как: присоединение по роли, но только если зарплата в Лондоне больше, чем в Вашингтоне, или у человека более длительный срок пребывания в должности.
```sql
ВЫБРАТЬ *
ОТ london_hq lhq
ПРИСОЕДИНЯЙТЕСЬ
ВКЛ lhq.role = whq.role
И (lhq.salary > whq.salary
ИЛИ lhq.tenure > whq.tenure)
Насколько я знаю, с пандами это невозможно. При присоединении (или слиянии) можно использовать только условие равенства.
Таким образом, вам нужно будет сначала выполнить JOIN для «роли», отслеживать происхождение каждого столбца, а затем фильтровать результат.
Тем не менее, я бы сказал, что эти условия по праву принадлежат JOIN и не менее актуальны из-за того, что не используется сравнение на равенство.
Ввод
Одним из основных преимуществ SQL является то, что каждый столбец имеет четко определенный тип. Кроме того, столбцы не могут иметь смешанные типы. Это избавляет от многих ошибок и головной боли в долгосрочной перспективе.
Когда вы загружаете данные в pandas, большинство столбцов автоматически печатаются как «объект». Это может означать одно из трех:
- Столбец содержит только строки
- Столбец содержит объекты Python, которые не являются примитивным типом данных, например. список или словарь
- Колонка содержит смешанные типы
Когда вы видите тип данных object
, вы никогда не знаете, что это такое. Я нахожу это очень раздражающим.
В отличие от SQL, вы можете загружать данные со смешанными типами в pandas: они будут просто типизированы как object
.
Pandas не заставляет вас указывать схему и придерживаться ее. Это дает вам преимущество в скорости, когда вы начинаете работу, но вы часто дорого платите за это будущими ошибками и путаницей.
Это особенно проблематично для новичков, которые не обращают внимания на распространенные ловушки. Например, когда я работал с Pandas, я часто пытался выполнить операцию даты и времени только для того, чтобы понять, что столбец даты и времени состоит из строк (поэтому классифицируется как «объект»). Я бы наивно сделал так:
```sql
df['Дата'] = df['Дата'].astype('datetime64[ns]')
И двигаться дальше, только чтобы узнать намного позже, что анализатор дат Pandas неправильно прочитал мои строки, и даты не имели смысла.
Файлы и CSV
Давайте будем честными: большинство людей хранят свои кадры данных в формате CSV. Студенты Pandas приветствуются, даже поощряются, чтобы сделать это. Это плохая идея!
Конечно, файлы CSV удобочитаемы, и... на этом их преимущества заканчиваются. Их недостатки:
- При преобразовании в CSV вы теряете всю информацию о схеме и типах столбцов. Все возвращается к тексту.
- CSV подвержены ошибкам форматирования, повреждениям и синтаксическому анализу.
- CSV трудно сжимать, что увеличивает затраты на хранение.
- Формат CSV не указан, что означает, что разные программы создают CSV по-разному, и нагрузка с пользователем, чтобы выяснить, как их анализировать. Это может быстро превратиться в ад, что подтвердит любой специалист по данным.
Потеря схемы, как правило, является самой большой проблемой для людей, работающих с пандами. Это распространенная ситуация:
- Ваша работа начинается с CSV. При условии, что вы определились с правильным форматированием, кодировкой, спецификацией кавычек и остальными множеством аргументов для панд.
read_csv
, вы загрузите его в кадр данных. Теперь вам нужно потратить время на изучение столбцов, приведение каждого столбца к правильному типу, устранение любых ошибок, возникающих в процессе, и проверку того, что конечный результат имеет смысл. (Или вы можете начать работать сразу и столкнуться с множеством ошибок позже).
- Как только ваша работа будет выполнена, у вас будет новый фрейм данных. что ты собираешься с этим делать? Почему, сохраните его как CSV. Теперь вся ваша предыдущая работа по определению схемы исчезла, поскольку фрейм данных сбрасывается в текст.
- Вам нужно загрузить новый фрейм данных для другого рабочего процесса. Это означает загрузку CSV, который вы только что выгрузили. Надеюсь, вы написали функции, которые могут успешно восстановить схему, иначе вам придется проделать всю работу заново (при условии, что вы помните, что должен был делать каждый столбец).
- Хотите поделиться файлом CSV с другом или опубликовать его на GitHub? Вам лучше поделиться кодом, который может переопределить схему, и надеяться, что они захотят и смогут ее запустить. Или у них останется кусок текста, и им придется повторять всю работу по вменению схемы с нуля.
Звучит абсурдно? Я видел, как это делается бесчисленное количество раз. Я сделал это сам! Но теперь мне интересно: почему мы учим людей так работать? Что оправдывает такое безумие и жестокость?
Здесь есть два решения.
Если вам действительно нужно работать в pandas, экспортируйте свои фреймы данных в Parquet.
Или вы могли бы работать в SQL и избавить себя от всех проблем. В конце концов, база данных — лучшее место для хранения данных.
Спросите себя: Зачем мне файловый слой? Если вы просто читаете какие-то данные, обрабатываете их, а затем сохраняете результаты, вы, вероятно, этого не сделаете. Загружать из базы, работать в базе, сохранять в базе. Это так просто. Нужно обмениваться данными извне? Экспорт в Паркет.
Миру не нужно больше CSV.
Примечание: некоторые люди пытаются решить проблему со схемой путем маринования своих фреймов данных. Это ужасная идея.
Травление неэффективно и небезопасно (никогда не открывайте соленье, которому не доверяете!). Маринованный кадр данных можно открыть только внутри Python, и это должно происходить в той же библиотечной среде (о которой пользователь может совершенно ничего не знать). Если версия pandas, которая читает рассол, отличается от версии pandas, которая его написала, файл может быть нечитаемым!
Нулевые значения
SQL использует значения NULL для обозначения отсутствующих данных. Вы можете легко отфильтровать нули.
```sql
ВЫБРАТЬ *
ОТ зарплаты
ГДЕ Equity_comp НЕ NULL
И cash_comp НЕ NULL
В Pandas отсутствующие значения могут быть любыми из следующих:
- Собственный Python
None
(который Pandas отображает какNone
, но обрабатывает какnan
)
numpy.nan
панды.NA
pandas.NaT
(для даты и времени)
Давайте сосредоточимся на numpy.nan, который является наиболее распространенным:
- Тип этого объекта
float
, так что забудьте о его обнаружении с помощью проверок типа.
- Это правда, так что забудьте о логических тестах.
bool(np.nan)
равноTrue
.
- Тест на равенство не проходит, так как
numpy.nan == numpy.nan
ложно.nan
не равно самому себе!
- Использование nan в операции не вызывает исключения, это просто означает, что результатом будет nan.
Разве это не весело?
Единственный способ обнаружить nan — это использовать pandas.isna(). Это нормально, как только вы прочитаете документы и забудете все свои питонические инстинкты. Тем не менее, такое поведение чрезвычайно сбивает с толку новичков.
Вот как вы можете воспроизвести приведенный выше запрос в Pandas:
```sql
new_df = df.dropna (подмножество = ["equity_comp", "cash_comp"])
Ограничения
[Ограничения] (https://www.w3schools.com/sql/sql_constraints.asp) важны в SQL. Они позволяют указать правила, обеспечивающие безопасность и согласованность ваших данных. Например, первичный ключ, который служит уникальным идентификатором для каждой строки, должен быть уникальным и не нулевым.
Ничего подобного в пандах нет.
Самое близкое к первичному ключу в pandas — это index. К сожалению, значение индекса может быть как повторяющимся, так и нулевым (да, у вас может быть индекс со значениями «Нет»).
Пользователи часто работают с неявным предположением, что индекс является первичным ключом, и эта идея поддерживается тем фактом, что индекс по умолчанию состоит из целых чисел: [0,1,2,3,4...]
. Следовательно, люди склонны использовать индекс для ссылки на определенные строки, например. df.loc[2]
.
Это глупый акт веры. Это становится очевидным при объединении или объединении различных фреймов данных. Часто бывает так, что похожие индексы перепутаны и получается индекс, который выглядит так: [0,1,2,2,2,3...]
.
Pandas не выдает никаких предупреждений об этом, поэтому вы сначала этого не понимаете. Но в следующий раз, когда вы будете использовать df.loc[2]
, ваш код сломается, потому что вместо одной строки он теперь будет возвращать фрейм данных с тремя строками.
Много слез прольется, прежде чем вы поймете, что вам нужно запустить reset_index()
для объединенного фрейма данных, чтобы каждая строка снова получила уникальное значение.
Кроме того, ограничения SQL позволяют запускать проверки во время записи. Если вы попытаетесь вставить нулевое значение в столбец, содержащий ограничение NOT NULL, вы получите исключение, и неправильная запись не произойдет. Pandas позволяет запускать проверки только при чтении. То есть, если вы не забудете это сделать.
Векторизованные операции
Это прежде всего педагогический момент. Pandas, как известно, допускает и даже поощряет векторизованные операции (где доступ ко всем элементам ряда осуществляется параллельно).
Но многие люди, работающие с Python, не думают так автоматически. Они начали с циклов обучения, а теперь от Гвидо, они хотят использовать эти циклы.
Когда они начинают работать с пандами, они вскоре обнаруживают методы «iterrows» и «itertuples», которые позволяют им зацикливать кадр данных по строкам.
Почти неизбежно они снова попадают в зацикленные паттерны, потому что ничто не заставляет их мыслить векторами. Это заставляет их писать ужасный код, который работает очень медленно.
Я начал сосредотачиваться на SQL после долгого опыта работы с пандами. Каждый раз, когда я сталкивался с проблемой SQL, я инстинктивно придумывал зацикленное решение. К сожалению, SQL не позволил мне сделать это.
Его декларативный синтаксис заставил меня задуматься об операциях со столбцами, JOIN и оконных функциях. Постепенно я построил новый набор ментальных моделей, которые сделали меня лучшим аналитиком.
Я думаю, что учащиеся должны научиться уверенно манипулировать данными в SQL, прежде чем начинать с pandas. Они будут лучше подготовлены, чтобы понять, когда зацикливание по строке неизбежно, что случается редко.
Неизменяемость
Вы загружаете кадр данных в память. Вам нужно изменить этот фрейм данных. Вы меняете его на месте или создаете копию? Стоит ли обновлять существующие столбцы или создавать новые?
Что, если вам нужно создать несколько срезов фрейма данных, а затем выполнить некоторую работу над каждым срезом? Следует ли хранить каждый срез в отдельной переменной или использовать одну и ту же переменную для хранения разных срезов по очереди?
Когда люди работают в пандах, они, как правило, делают все эти вещи одновременно. Вскоре становится трудно отслеживать все переменные, содержащие фреймы данных, срезы фреймов данных и слайсы слайсов, и знать, как данные были добавлены или изменены.
(Я не всегда пишу панды, но когда я это делаю, я получаю [настройка с предупреждением о копировании] (https://realpython.com/pandas-settingwithcopywarning/).)
А поскольку большинство людей используют панды с ноутбуками, эти проблемы усугубляются типичными [подводными камнями ноутбуков] (https://docs.google.com/presentation/d/1n2RlMdmv1p25Xy5thJUhkKGvjtV-dkAIsUXP-AL4ffI) и в конечном итоге вызывают огромные головные боли.
Это одна из причин, почему я считаю, что pandas — не лучший вариант для анализа данных.
При обработке данных в SQL исходные данные не изменяются. Оператор UPDATE не используется в аналитике. Вместо этого вы создаете конвейеры таблиц и представлений, которые представляют различные выборки.
Когда вам нужно сохранить результаты, вы создаете новые таблицы (или добавляете строки в существующие целевые таблицы, но без изменения или удаления предыдущих строк). Это соответствует принципу неизменяемости: никогда не изменять и не удалять исходные данные. Это делает ваш процесс безопасным, прозрачным и легко воспроизводимым.
Да, вы можете уважать неизменность в пандах, но не очевидно, что вы должны это делать, и многие люди никогда не учатся этому. Обычно вы видите неизменность на уровне файлов: люди обычно загружают CSV и выводят новый CSV. Но для работы, которая происходит между ними? Все идет.
(Большинство методов pandas теоретически «чисты», потому что они возвращают новый фрейм данных вместо изменения предыдущего. Но все они предоставляют опцию «inplace», которая изменяет фрейм данных на месте. И люди используют его с удовольствием.)
Когда панд недостаточно
Если вы серьезно работаете с пандами, вы в конечном итоге столкнетесь со стеной производительности. Данные, которые вы анализируете, слишком велики, или ваши потребности в обработке слишком высоки.
Я часто видел это, когда проводил исследования с пандами. Когда это случалось, мы с коллегами гуглили «сделать панд быстрее» и находили бесчисленные статьи на эту горячую тему, которые, в свою очередь, предлагали бесчисленные хаки, оптимизации и библиотеки PyPI, которые обещали сделать свое дело.
Если вы находитесь в такой ситуации, обязательно ознакомьтесь с доступными ресурсами. Особенно те, которые объясняют, как [лучше использовать pandas] (https://towardsdatascience.com/how-to-make-your-pandas-operation-100x-faster-81ebcd09265c). Но не возлагайте слишком большие надежды. Существуют жесткие ограничения на то, что могут делать панды. Это нормально: он не был разработан, чтобы положить конец всей аналитике данных.
Две лучшие альтернативы, когда вам нужно масштабировать свои рабочие нагрузки данных:
- PySpark. Spark — это механизм крупномасштабной аналитики и параллельной обработки данных. PySpark позволяет использовать его с Python и использует синтаксис, напоминающий pandas. У него даже есть API панд.
- Хранилище данных. Система для хранения и анализа данных в очень больших масштабах (например, терабайты и петабайты). Современные хранилища данных работают в облаке, поэтому вы можете использовать мощь распределенных систем без управления серверами. BigQuery, решение для хранилища данных Google Cloud, может обрабатывать 100 миллиардов строк или 7 терабайт данных за 30 секунд . Хранилища данных обычно работают с SQL. (Если вы хотите попробовать BigQuery бесплатно, я писал об этом здесь. )
Когда Pandas лучше?
Я не хочу, чтобы вы избегали панд. Это потрясающий инструмент, который определенно стоит изучить.
Есть есть случаи, когда панды - лучший выбор, чем SQL. Я не буду вдаваться в подробности здесь, но вот краткий список:
- При интеграции с другими рабочими процессами Python, например. вы занимаетесь машинным обучением или хотите использовать библиотеку визуализации Python.
- Когда вам нужна быстрая статистика. Метод
describe()
очень полезен.
- Когда вам нужно провести быстрый анализ, не беспокоясь о масштабе или воспроизводимости. Хотя Excel или Google Таблицы могут работать так же хорошо.
- Если вы создаете приложения Python. Панды могут быть самым быстрым способом перехода от произвольной структуры данных к таблице и наоборот.
- Когда вам на самом деле нужны императивные рабочие процессы и циклы. Например. построение марковских симуляций.
- Когда вам нужно написать или повторно использовать необычные функции. Pandas отлично подходит для применения произвольных функций Python.
- Если у вас очень динамичный и параметризованный рабочий процесс.
Вывод
Я надеюсь, что эта статья побудила вас глубже задуматься о SQL и pandas, а также об их сильных и слабых сторонах.
Я считаю, что текущая тенденция в области данных слишком сильно изменилась в пользу панд, и что вы игнорируете SQL на свой страх и риск.
Вот мой совет:
- Если вы учитесь: изучите SQL и научитесь использовать его для своей аналитики. Вы не пожалеете об этом.
- Если вы разработчик учебных программ: утопите своих учеников в SQL, пока они не будут мечтать в таблицах и говорить заглавными буквами. Это тяжелая любовь, и они будут ненавидеть вас за это, но когда наступит день, они поймут. (Не бейте их по голове.)
- Если вы наставник: старайтесь постепенно отучать своих учеников от Pandas и поощряйте их решать задачи на SQL.
- Я хотел бы продолжить разговор. Не стесняйтесь оставлять комментарии, [напишите мне по электронной почте] (https://writeto:vlad.publish@gmail.com) или добавьте меня в [LinkedIn] (https://www.linkedin.com/in/vlad- дс/).*
Оригинал