Найти тему
Nuances of programming

7 полезных операций в Pandas при работе с DataFrame

Оглавление

Источник: Nuances of Programming

Абстракция датафрейма является одной из наиболее полезных концепций в современной экосистеме управления данными. Вращается она главным образом вокруг табличных структур, которые имеют повышенную производительность при обновлении и запросе данных различными способами. Сериализация/десериализация этих структур из/в различные форматы файлов упрощает работу с данными. Более того, возможность производить различные SQL-подобные операции, такие как объединение, наряду с выполнением математических вычислений в самом датафрейме существенно расширяет возможности программиста.

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

1. Конкатенация DataFrame

Есть два способа конкатенировать датафрейм A и B. Представьте их как проиндексированные таблицы. Эти две таблицы можно объединить либо по оси y, либо по оси x.

Если требуется конкатенировать их вдоль x, то вызов API будет таким:

import pandas as pdpd.concat([A, B], axis=1)

Если же вдоль y, то таким:

import pandas as pdpd.concat([A, B]) # по умолчанию axis = 0

Применение

Предположим, у вас есть большое количество CSV-файлов или XLSX-данных, которые нужно присоединить друг к другу. Одним из способов сделать это будет считать данные файлов в датафреймы и использовать инструкцию pd.concat([file_1, file_2]). Программно можно перебрать имена файлов (используя модуль glob для чтения набора имен файлов с помощью техники сопоставления шаблонов, например regex), считать их в датафрейм, соединить в памяти и сериализовать конкатенированные датафреймы в нужный формат файлов.

Вариант с axis = 0 используется нечасто, но его можно применять в сценариях, когда нужно обработать массивы данных, собранных с упорядочиванием. То есть, когда последовательность данных соответствует последовательности других массивов данных. В таком случае эти массивы можно объединить вдоль оси x, получив более объемное и значительное представление в табличном формате. Затем к полученной структуре можно применять операции, использующие все типы данных в ее столбцах.

2. Разделение DataFrame

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

Просмотр сведений

В некоторых сценариях, особенно при написании кода с помощью блокнотов (например Jupyter), мы заглядываем в датафрейм, только чтобы понять, как он выглядит. В таких случаях можно использовать метод head().

import pandas as pdprint(df.head(10)) # выводит первые 10 строк dataframe

Исключение столбцов

Этот метод разделяет датафрейм вдоль оси y, то есть просто выбрасывает из него часть столбцов. Используется данный метод в типичном сценарии, когда нам не нужно, чтобы конечный DataFrame содержал эти столбцы, или когда мы предполагаем, что при дальнейшем обновлении структура станет занимать слишком много памяти.

import pandas as pddf.drop('COLUMN_NAME', inplace=True, axis=1)
# указывает, что 'COLUMN_NAME' находится на оси x

Удаление датафреймов друг из друга

Представим, что у нас есть датафрейм X, состоящий из столбцов [A, B, C, D], и датафрейм Y, состоящий из подмножества столбцов X. Нам нужно удалить Y из X. Это можно сделать так:

import pandas as pdpd.concat([X, Y]).drop_duplicates(keep=False)

Конкатенация этих датафреймов приведет к дублированию общих записей, которые в итоге будут удалены выражением keep = false функции drop_duplicates().

Применение

Предположим, что столбец A — это определенный вид ID сведений о работнике. К примеру, датафрейм X состоит из всех данных о работниках, а датафрейм Y содержит данные (с той же структурой) о работниках, не разбирающихся в Python. Нам нужно отфильтровать сведения о сотрудниках, которые не знакомы с Python.

Определение дельты записей на основе столбца

Представим, что у нас есть датафрейм X, состоящий из столбцов [A, B, C, D], а также датафрейм Y, состоящий из тех же столбцов. При этом некоторые элементы столбцов A этих датафреймов являются общими. Нам нужно получить из датафрейма X строки, которые не содержат значения из столбца A, находящиеся в столбце A датафрейма Y.

import pandas as pdX[~X['A'].isin(Y['A'])]

Применение

Взгляните на эту таблицу:

Небольшая часть пар записей о работниках
Небольшая часть пар записей о работниках

Эти пары могли быть сгенерированы, например, из двух журналов: старого и нового. Нам нужно найти пары ID, принадлежащие одному и тому же человеку. Предположим, что ваш отдел кадров неожиданно заявляет, что определенный список (hr_list) сотрудников с ID_1 больше в компании не работает. Как удалить их из этого датафрейма?

import pandas as pdfiltered_pairs = employee_pairs[~employee_pairs['ID_1'].isin(hr_list)]

Разделение на основе значений столбцов

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

import pandas as pdfiltered_df = df[~df['A'].isna() & (df['B'] > 10)]
# Возвращает строки, где столбец A не null, а значение столбца B больше 10.

Это простейший пример.

3. Подсчет записей в столбце

Это эффективный способ определения количества различных элементов в столбце.

Как часто каждая страна принимала кубок Азии по крикету с 1984 по 2014 год?
Как часто каждая страна принимала кубок Азии по крикету с 1984 по 2014 год?

Ответ на приведенный выше запрос можно получить следующим подходом:

4. Чтение фрагментов DataFrame

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

import pandas as pdpd.read_csv('file.csv', usecols=['A', 'B'])
# Считать только столбцы 'A' и 'B'

Более того, можно считывать большие файлы в отдельные фрагменты и маршалировать их в датафреймы.

import pandas as pdfor chunk in pd.read_csv('file.csv', chunksize=1000):
process(chunk)

Таким образом одновременно в памяти удерживается только фрагмент размером chunksize.

5. Применение функций к строкам

Бывают случаи, в которых требуется внести изменения в конкретные столбцы детафрейма. К примеру, в датафрейме X, содержащем столбцы A, B и C, мы можем применить функцию f() к значениям столбца B, чтобы сохранить их в столбце D.

import pandas as pddf['D'] = df.apply(lambda row: f(row['B'], row['C']), axis=1)

Эта операция окажется намного быстрее, чем перебор всего датафрейма с помощью iterrows().

Есть и альтернативный метод. Его можно использовать, когда функцию f() требуется применить только к одному столбцу.

import pandas as pddf['D'] = df['B'].map(lambda b: f(b))

6. Объединение двух датафреймов

По аналогии с реляционными базами данных датафреймы можно объединять merge , используя разрешающий столбец.

import pandas as pdpd.merge(left=df_a, left_on['A'], right=df_b, right_on=['B'], how='inner')
# Также работает для left и right объединения.

Однако стоит заметить, что операция merge является дорогостоящей, в связи с чем перед слиянием больших датасетов стоит проявлять особое внимание. В случаях, когда датасеты слишком велики, рекомендуется использовать методы группировки (англ.), чтобы избежать перегрузки памяти и связанных с этим проблем производительности.

7. Переименование столбцов

Переименовывать столбцы особенно полезно перед сериализацией файла или перед внедрением стороннего хранилища данных.

import pandas
df = df.rename(columns={
"A_1": "A" "B_1": "B" })
# переименовывает оригинальные столбцы ["A_1", "B_1"] в ["A", "B"].

Читайте также:

Читайте нас в Telegram, VK

Перевод Dasun Pubudumal: 7 Useful Pandas Operations To Use on DataFrames