Share This
Связаться со мной
Крути в низ
Categories
//🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 8348c32 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Разработчик ПО (системы PDM/PLM) с 1993 года, компания "ИНТЕРМЕХ" (www.intermech.ru). В 2020-м успешно закончил курсы "Основы Data Science" (минская IT Academy) Референт-переводчик технической литературы с английского языка. Новые и малоизвестные возможности Pandas, о которых полезно знать каждому специалисту по Data Science.

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 1c72256 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Сколько раз вы говорили: «было бы здорово, если бы я мог это сделать в Pandas»?

Возможно, вы это и можете! Pandas настолько огромна и глубока, что она позволяет выполнять практически любые операции с таблицами, которые вы можете себе представить. Однако подобная глубина имеет свою цену. Многие элегантные возможности, решающие редко возникающие задачи и уникальные сценарии, теряются в глубинах документации, затертые более часто используемыми функциями.

Эта статья попытается заново открыть для вас многие возможности Pandas и показать, что она может намного больше, чем вам казалось.

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 217233d - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Erik Mclean. Источник Pexels

1. ExcelWriter

ExcelWriter – это обобщенный класс для создания файлов Excel (с листами!) и записи в них DataFrame. Допустим, у нас есть два набора данных:

         # Загрузим два набора данных diamonds = sns.load_dataset("diamonds") tips = sns.load_dataset("tips")  # Пишем оба в один и тот же файл Excel with pd.ExcelWriter("data/data.xlsx") as writer:     diamonds.to_excel(writer, sheet_name="diamonds")     tips.to_excel(writer, sheet_name="tips")     

У класса есть дополнительные атрибуты для определения используемого формата DateTime: хотите ли вы создать новый файл Excel или изменить существующий, что делать, если лист существует и т. п. Детали см. в документации.

2. pipe

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 2ec7997 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Leah Kelley. Источник Pexels

pipe – одна из лучших функций для проведения очистки данных в Pandas кратким и четким образом. Она позволяет объединять несколько пользовательских функций в одну операцию.

Для примера допустим, что у вас есть функции удаления дубликатов (remove_duplicates), удаления выбросов (remove_outliers) и кодирования категориальных признаков (encode_categoricals), каждая со своими аргументами. Вот как вы можете применить все эти функции одной операцией:

         df_preped = (diamonds.pipe(drop_duplicates).                       pipe(remove_outliers, ['price', 'carat', 'depth']).                       pipe(encode_categoricals, ['cut', 'color', 'clarity'])             )     

Мне нравится, что эта функция похожа на конвейеры Sklearn. Вы можете сделать с ее помощью намного больше – читайте документацию или эту полезную статью.

Больше полезной информации вы найдете на нашем телеграм-канале «Библиотека data scientist’а» Интересно, перейти к каналу

3. factorize

Эта функция – альтернатива LabelEncoder из Sklearn в Pandas:

         # Обратите внимание на [0] в конце diamonds["cut_enc"] = pd.factorize(diamonds["cut"])[0]  >>> diamonds["cut_enc"].sample(5)  52103    2 39813    0 31843    0 10675    0 6634     0 Name: cut_enc, dtype: int64     

В отличие от LabelEncoder‘а, factorize возвращает кортеж из двух значений: закодированный столбец и список уникальных категорий.

         codes, unique = pd.factorize(diamonds["cut"], sort=True)  >>> codes[:10] array([0, 1, 3, 1, 3, 2, 2, 2, 4, 2], dtype=int64)  >>> unique ['Ideal', 'Premium', 'Very Good', 'Good', 'Fair']     

4. explode – Бабах!

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 88a84de - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Joshua Sukoff. Источник Unsplash

explode – это функция с интересным именем (взрыв). Давайте сначала посмотрим пример, а потом объясним:

         data = pd.Series([1, 6, 7, [46, 56, 49], 45, [15, 10, 12]]).to_frame("dirty")  >>> data     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 ab9d9c7 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

В столбце dirty есть две строки, в которых хранятся не единственные значения, а списки. Такие данные часто встречаются в опросах, поскольку некоторые вопросы допускают несколько ответов.

         >>> data.explode("dirty", ignore_index=True)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 b52a768 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

explode распространяет данные из ячейки с массивоподобным значением на несколько строк. Установите ignore_index в True, чтобы сохранить числовой индекс по порядку.

5. squeeze

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 f88ca00 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор cottonbro. Источник Pexels

Еще одна функция с забавным именем – это squeeze (сжатие), используемая в очень редких, но надоедливых случаях. Один из таких случаев – когда запрос подмножества из DataFrame возвращает единственное значение. Рассмотрим следующий пример:

         subset = diamonds.loc[diamonds.index < 1, ["price"]]  >>> subset     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 2679b5b - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Хотя результат – всего одна ячейка, он возвращается как DataFrame. Это неудобно, поскольку вам придется еще раз использовать .loc и передать как имя столбца, так и индекс, чтобы получить цену.

Но если вы знаете про squeeze, нам не придется этого делать. Эта функция позволяет убрать оси из DataFrame или Series, содержащих единственную ячейку. Например:

         >>> subset.squeeze() 326     

Теперь мы получили скалярное значение. Можно также указать, какую ось нужно убрать:

         >>> subset.squeeze("columns")  # или "rows"  0    326 Name: price, dtype: int64     

Обратите внимание, что squeeze работает только с DataFrame и Series, имеющими единственное значение.

6. between

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 c4293b3 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Justin Dream. Источник Pexels

Это довольно изящная функция для бинарного индексирования числовых признаков по принадлежности диапазону:

         # Выбрать бриллианты с ценой от 3500 до 3700 долларов diamonds[diamonds["price"]       .between(3500, 3700, inclusive="neither")].sample(5)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 3b096c3 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

7. T

У всех DataFrame есть простой атрибут T, что значит «транспонирование». Возможно, вы не будете часто его использовать, но я считаю его довольно полезным при выводе DataFrame’ов после метода describe():

         >>> boston.describe().T.head(10)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 e57d1e0 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Набор данных о недвижимости Бостона содержит 30 числовых столбцов. Если просто вызвать describe, результирующий DataFrame будет сжат по горизонтали, и сравнить статистику будет трудно. Транспонирование поменяет оси местами, и по горизонтали будут уже статистические параметры.

8. Стилизатор Pandas

А вы знали, что Pandas позволяет вам задавать стили DataFrame’ов?

У них есть атрибут style, открывающий дверь к настройкам и стилям, ограниченным только вашими знаниями HTML и CSS. Я не буду рассказывать обо всем, что вы можете сделать с помощью style, покажу лишь свои любимые функции:

         >>> diabetes.describe().T.drop("count", axis=1)                  .style.highlight_max(color="darkred")     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 51fba36 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Мы выделили ячейки, содержащие максимальные значения каждого столбца. Еще один полезный стилизатор – background_gradient, присваивающий ячейкам градиентный фоновый цвет на основе их значений:

         diabetes.describe().T.drop("count", axis=1).style.background_gradient(     subset=["mean", "50%"], cmap="Reds" )     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 b5daeb6 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Это особенно полезно, если вы вызываете describe для таблицы со множеством столбцов и хотите сравнить суммарную статистику. Подробности см. в документации по стилизатору.

9. Опции Pandas

Как и в Matplotlib, в Pandas есть глобальные настройки, которые можно изменять для настройки поведения по умолчанию:

         >>> dir(pd.options) ['compute', 'display', 'io', 'mode', 'plotting']     

Эти настройки разделены на 5 модулей. Давайте посмотрим, какие настройки есть в модуле display:

         >>> dir(pd.options.display)  ['chop_threshold',  'max_columns',  'max_colwidth',  'max_info_columns',  'max_info_rows',  'max_rows',  ...  'precision',  'show_dimensions',  'unicode',  'width']     

В группе display много настроек, но я в основном использую max_columns и precision:

         # Убрать лимит на изображаемое количество столбцов pd.options.display.max_columns = None  # Показывать только 5 цйфр после запятой pd.options.display.precision = 5  # избавиться от научной нотации     

Больше подробностей об этих замечательных настройках можно найти в документации.

10. convert_dtypes

Все мы знаем, что Pandas имеет раздражающую привычку присваивать столбцам тип данных object. Вместо того чтобы назначать типы данных вручную, вы можете использовать метод convert_dtypes, который пытается подобрать наиболее подходящий тип данных:

         sample = pd.read_csv(     "data/station_day.csv",     usecols=["StationId", "CO", "O3", "AQI_Bucket"], )  >>> sample.dtypes  StationId      object CO            float64 O3            float64 AQI_Bucket     object dtype: object  >>> sample.convert_dtypes().dtypes  StationId      string CO            float64 O3            float64 AQI_Bucket     string dtype: object     

К сожалению, метод не может разбирать даты из-за нюансов различных форматов их представления.

11. select_dtypes

Функция, которую я использую постоянно – это select_dtypes. Ее функционал очевиден из ее названия: выбор по типам данных. У нее есть параметры include и exclude, позволяющие выбрать столбцы, включая или исключая определенные типы данных. Например, можно выбрать только числовые столбцы, указав np.number:

         # Выбрать только числовые столбцы diamonds.select_dtypes(include=np.number).head()     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 54ae314 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

или, наоборот, исключить их:

         # Исключить числовые столбцы diamonds.select_dtypes(exclude=np.number).head()     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 fa01aab - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

12. mask

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 4d0e0b6 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Pixabay. Источник Pexels.

Функция mask позволяет быстро заменять значения в тех ячейках, для которых выполняется определенное условие. Предположим, что у нас есть данные опроса людей от 50 до 60:

         # Create sample data ages = pd.Series([55, 52, 50, 66, 57, 59, 49, 60]).to_frame("ages")  ages     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 eb7bf70 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Мы будем считать возраст, выходящий за границы от 50 до 60 лет, ошибками ввода (таких ошибок две – 49 и 66 лет), которые заменим на NaN:

         ages.mask(cond=~ages["ages"].between(50, 60), other=np.nan)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 1ad6427 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Таким образом, mask заменяет значения ячеек, не удовлетворяющие cond, значениями other.

13. min и max по строкам и столбцам

Хотя функции min и max широко известны, они имеют еще одно применение, полезное для особых случаев. Давайте рассмотрим следующий набор данных:

         index = ["Diamonds", "Titanic", "Iris", "Heart Disease", "Loan Default"] libraries = ["XGBoost", "CatBoost", "LightGBM", "Sklearn GB"]  df = pd.DataFrame(     {lib: np.random.uniform(90, 100, 5) for lib in libraries}, index=index )  >>> df     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 9af4813 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Этот DataFrame содержит воображаемую точность моделей, полученных в результате четырех видов градиентного бустинга на пяти различных наборах данных. Мы хотим найти лучшую точность на каждом наборе. Вот как элегантно это можно сделать с помощью max:

         >>> df.max(axis=1)  Diamonds         99.52684 Titanic          99.63650 Iris             99.10989 Heart Disease    99.31627 Loan Default     97.96728 dtype: float64     

Если вы хотите найти максимум или минимум по каждому столбцу, достаточно изменить 1 на 0.

14. nlargest и nsmallest

Иногда вам недостаточно получить максимальное или минимальное значение столбца. Вы хотите получить N максимальных (или минимальных) значений. Для этого пригодятся функции nlargest и nsmallest. Давайте выведем 5 самых дорогих и самых дешевых бриллиантов:

         diamonds.nlargest(5, "price")     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 5a54103 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

         diamonds.nsmallest(5, "price")     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 a97078f - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

15. idxmax и idxmin

Когда вы вызываете max или min для столбца, pandas возвращает максимальное или минимальное значение. Однако иногда вам нужна позиция этого значения, а не оно само. Для этого используйте функции idxmax и idxmin:

         >>> diamonds.price.idxmax() 27749  >>> diamonds.carat.idxmin() 14     

Можно также задать axis=’columns’, при этом функции будут возвращать номер индекса нужного столбца.

16. value_counts с параметром dropna=False

Для нахождения процента пропущенных значений чаще всего используется комбинация isnull и sum и деление на длину массива. Но вы можете сделать то же самое с помощью value_counts, если задать соответствующие аргументы:

         ames_housing = pd.read_csv("data/train.csv")  >>> ames_housing["FireplaceQu"].value_counts(dropna=False, normalize=True)  NaN    0.47260 Gd     0.26027 TA     0.21438 Fa     0.02260 Ex     0.01644 Po     0.01370 Name: FireplaceQu, dtype: float64     

В этом столбце 47% пустых значений (NaN).

17. clip

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 4ad2d0e - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Автор Ann H. Источник Pexels

Обнаружение и удаление выбросов часто используется в анализе данных. Функция clip позволяет очень легко найти выбросы, выходящие за пределы диапазона и заменить их предельными значениями. Давайте вернемся к примеру с возрастами людей от 50 до 60:

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 a034535 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

На этот раз мы заменим значения, выходящие за диапазон от 50 до 60, крайними значениями диапазона.

         ages.clip(50, 60)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 71375a7 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Быстро и эффективно!

18. at_time и between_time

Эти функции могут пригодиться при работе с данными, разделенными по времени с высокой степенью детализации. Давайте создадим таблицу, содержащую 100 часовых интервалов:

         index = pd.date_range("2021-08-01", periods=100, freq="H") data = pd.DataFrame({"col": list(range(100))}, index=index)  >>> data.head()     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 a11801f - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Функция at_time позволяет выбирать значения по заданным дате или времени. Давайте выделим все строки, соответствующие 15.00:

         data.at_time("15:00")     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 c84b218 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Здорово, правда? А теперь давайте используем between_time, чтобы выделить строки в заданном интервале времени:

         from datetime import datetime  >>> data.between_time("09:45", "12:00")     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 9438cc6 - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Заметьте, что обе функции требуют DateTimeIndex, и они работают только с временем. Если вы хотите выделить строки в определенном интервале DateTime, используйте between.

19. bdate_range

bdate_range – это функция для быстрого создания индексов TimeSeries с частотой в один бизнес-день.

         series = pd.bdate_range("2021-01-01", "2021-01-31")  # A period of one month  >>> len(series) 21     

Частота в бизнес-день часто встречается в финансовом мире. Значит, эта функция может оказаться полезной для переиндексирования существующих временных интервалов функцией reindex.

20. autocorr

Один из важнейших компонентов анализа временных последовательностей – это изучение автокорреляции переменной. Автокорреляция – это старый добрый коэффициент корреляции, но взятый по сравнению с лагом той же последовательности. Точнее, автокорреляция при lag=k вычисляется следующим образом:

1. Последовательность сдвигается k периодов времени:

         time_series = tips[["tip"]] time_series["lag_1"] = time_series["tip"].shift(1) time_series["lag_2"] = time_series["tip"].shift(2) time_series["lag_3"] = time_series["tip"].shift(3) time_series["lag_4"] = time_series["tip"].shift(4) # time_series['lag_k'] = time_series['tip'].shift(k)  >>> time_series.head()     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 c5c4def - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

2. Рассчитывается корреляция между исходным значением и каждым лагом.

Вместо того чтобы делать все это вручную, вы можете использовать функцию Pandas autocorr:

         # Автокорреляция tip при lag_8 >>> time_series["tip"].autocorr(lag=8) 0.07475238789967077     

О важности автокорреляции для анализа временных рядов можно прочитать в этой статье.

21. hasnans

Pandas предлагает метод для простой проверки, содержит ли Series какие-либо пустые значения – атрибут hasnans:

         series = pd.Series([2, 4, 6, "sadf", np.nan])  >>> series.hasnans True     

Согласно его документации, атрибут существенно ускоряет производительность. Заметьте, что он работает только для Series.

22. at и iat

Эти два метода доступа к значениям – гораздо более быстрые альтернативы loc и iloc, но с существенным недостатком: они позволяют получить или изменить только одно значение:

         # [index, label] >>> diamonds.at[234, "cut"] 'Ideal'  # [index, index] >>> diamonds.iat[1564, 4] 61.2  # Заменить 16541-ю строку столбца price >>> diamonds.at[16541, "price"] = 10000     

23. argsort

Эту функцию стоит использовать каждый раз, когда вы хотите выделить индексы, образующие отсортированный массив:

         tips.reset_index(inplace=True, drop=True)  sort_idx = tips["total_bill"].argsort(kind="mergesort")  # Теперь выведем значения `tips` в порядке сортировки по total_bill tips.iloc[sort_idx].head()     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 feda7ac - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

24. Метод доступа cat

Общеизвестно, что Pandas позволяет использовать встроенные функции Python на датах и строках с помощью методов доступа вроде dt или str. Кроме того, в Pandas есть специальный тип данных category для категориальных переменных, как показано ниже:

         >>> diamonds.dtypes  carat       float64 cut        category color      category clarity    category depth       float64 table       float64 price         int64 x           float64 y           float64 z           float64 cut_enc       int64 dtype: object     

Если столбец имеет тип category, над ним можно выполнять несколько специальных функций с помощью метода доступа cat. Например, давайте рассмотрим различные виды огранки бриллиантов:

         >>> diamonds["cut"].cat.categories ['Ideal', 'Premium', 'Very Good', 'Good', 'Fair']     

Есть и такие функции, как remove_categories, rename_categories и т. д.:

         diamonds["new_cuts"] = diamonds["cut"].cat.rename_categories(list("ABCDE"))  >>> diamonds["new_cuts"].cat.categories Index(['A', 'B', 'C', 'D', 'E'], dtype='object')     

Полный список функций, доступных через метод доступа cat, можно посмотреть здесь.

25. GroupBy.nth

Эта функция работает только для объектов GroupBy. После группировки она возвращает n-ю строку каждой группы:

         diamonds.groupby("cut").nth(5)     

25 vozmozhnostej pandas o kotoryh vy ne znali infa 80 20c44bf - 🐼 25 возможностей Pandas, о которых вы не знали (инфа 80%)

Заключение

Несмотря на то, что новые библиотеки вроде Dask и datatable потихоньку вытесняют Pandas благодаря их сверкающим новым возможностям для обработки огромных массивов данных, Pandas по-прежнему остается самым популярным средством манипуляции данными в экосистеме Data Science на Python.

Эта библиотека – образец для подражания, который другие пытаются имитировать и улучшить, поскольку она прекрасно интегрируется в современный стек SciPy.

Спасибо за внимание!

***

Материалы по теме

  • 📊 Инструменты дата-журналиста #1: Jupyter Notebook и библиотека Pandas
  • 🤖 Numpy, Pandas, matplotlib – необходимый минимум для старта в Machine Learning
  • 📊Django, Pandas и Chart.js для быстрой панели инструментов

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован.

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    blank
    Roman Spiridonov

    Моя специальность - Back-end Developer, Software Engineer Python. Мне 39 лет, я работаю в области информационных технологий более 5 лет. Опыт программирования на Python более 3 лет. На Django более 2 лет.

    Categories 05.

    © Speccy 2022 / All rights reserved

    Связаться со мной
    Close