Некоторые из самых полезных трюков Pandas

Pandas - потрясающая библиотека, которая содержит обширные встроенные функции для управления данными. Среди них transform() очень полезен, когда вы хотите управлять строками или столбцами.

В этой статье мы рассмотрим следующие наиболее часто используемые transform() функции Pandas:

  1. Преобразование ценностей
  2. Объединение groupby() результатов
  3. Фильтрация данных
  4. Обработка пропущенного значения на уровне группы

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

1. Преобразование ценностей

Давайте посмотрим на pd.transform(func, axis=0)

  • Первый аргумент func - указать функцию, которая будет использоваться для управления данными. Это может быть функция, строковое имя функции, список функций или словарь меток осей - ›функции
  • Второй аргумент axis указывает, к какой оси применяется func. 0 для применения func к каждому столбцу и 1 для применения func к каждой строке.

Давайте посмотрим, как transform() работает, на нескольких примерах.

Функция

Мы можем передать функцию func. Например

df = pd.DataFrame({'A': [1,2,3], 'B': [10,20,30] })
def plus_10(x):
    return x+10
df.transform(plus_10)

Вы также можете использовать лямбда-выражение. Ниже приведен лямбда-эквивалент plus_10() :

df.transform(lambda x: x+10)

Строковая функция

Мы можем передать любую допустимую строковую функцию Pandas в func, например 'sqrt':

df.transform('sqrt')

Список функций

func может быть списком функций. например sqrt и exp из NumPy:

df.transform([np.sqrt, np.exp])

Табличка осей - ›функция

func может быть обозначением осей - ›функция. Например

df.transform({
    'A': np.sqrt,
    'B': np.exp,
})

2. Объединение groupby() результатов

Одно из наиболее убедительных применений Pandas transform() - комбинирование grouby() результатов.

Давайте посмотрим, как это работает, на примере. Предположим, у нас есть набор данных о сети ресторанов.

df = pd.DataFrame({
  'restaurant_id': [101,102,103,104,105,106,107],
  'address': ['A','B','C','D', 'E', 'F', 'G'],
  'city': ['London','London','London','Oxford','Oxford', 'Durham', 'Durham'],
  'sales': [10,500,48,12,21,22,14]
})

Мы видим, что в каждом городе есть несколько ресторанов с распродажами. Мы хотели бы знать, «Какой процент продаж представляет каждый ресторан в городе». Ожидаемый результат:

Сложность в этом вычислении заключается в том, что нам нужно получить city_total_sales и снова объединить его с данными, чтобы получить процент.

Есть 2 решения:

  1. groupby(), apply() и merge()
  2. groupby() и transform()

Решение 1. groupby(), apply() и merge()

Первое решение - разделить данные с помощью groupby() и использовать apply() для агрегирования каждой группы, а затем объединить результаты обратно в исходный DataFrame с помощью merge()

Шаг 1. Используйте groupby() и apply() для расчета city_total_sales

city_sales = df.groupby('city')['sales']
             .apply(sum).rename('city_total_sales').reset_index()

groupby('city') разделите данные, сгруппировав их по столбцу города. Для каждой из этих групп функция sum применяется к столбцу продажи для вычисления суммы для каждой группы. Наконец, новый столбец переименовывается в city_total_sales, а индекс сбрасывается (примечание: reset_inde() требуется для очистки индекса, созданного groupby('city')).

Кроме того, в Pandas есть встроенная функция sum(), а следующий sum() эквивалент Pandas:

city_sales = df.groupby('city')['sales']
             .sum().rename('city_total_sales').reset_index()

Шаг 2. Используйте функцию merge(), чтобы объединить результаты

df_new = pd.merge(df, city_sales, how='left')

Результаты группы объединяются обратно в исходный DataFrame с использованием merge() с how='left' для левого внешнего соединения.

Шаг 3. Рассчитайте процент

Наконец, процентное соотношение можно рассчитать и отформатировать.

df_new['pct'] = df_new['sales'] / df_new['city_total_sales']
df_new['pct'] = df_new['pct'].apply(lambda x: format(x, '.2%'))

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

Мы можем эффективно решить эту проблему с помощью функции transform().

Решение 2: groupby() и transform()

Это решение меняет правила игры. Одна строка кода может решить применить и объединить.

Шаг 1. Используйте groupby() и transform() для расчета city_total_sales

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

df['city_total_sales'] = df.groupby('city')['sales']
                           .transform('sum')

Шаг 2. Рассчитайте процент

Наконец, это то же самое, что и решение для получения процента.

df['pct'] = df['sales'] / df['city_total_sales']
df['pct'] = df['pct'].apply(lambda x: format(x, '.2%'))

3. Фильтрация данных

transform() также можно использовать для фильтрации данных. Здесь мы пытаемся получить рекорды, когда общий объем продаж в городе превышает 40

df[df.groupby('city')['sales'].transform('sum') > 40]

4. Обработка пропущенных значений на уровне группы

Еще одно использование Pandas transform() - обработка пропущенных значений на уровне группы. Давайте посмотрим, как это работает, на примере.

Вот DataFrame для демонстрации

df = pd.DataFrame({
    'name': ['A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
    'value': [1, np.nan, np.nan, 2, 8, 2, np.nan, 3]
})

В приведенном выше примере данные можно разделить на три группы по имени, и в каждой группе отсутствуют значения. Распространенное решение заменить отсутствующие значения - заменить NaN на среднее.

Давайте посмотрим на среднее значение в каждой группе.

df.groupby('name')['value'].mean()
name
A    1.0
B    5.0
C    2.5
Name: value, dtype: float64

Здесь мы можем использовать transform() для замены отсутствующих значений средним значением группы.

df['value'] = df.groupby('name')
                .transform(lambda x: x.fillna(x.mean()))

Вот и все

Спасибо за прочтение.

Пожалуйста, загляните в записную книжку на моем Github, чтобы найти исходный код.

Следите за обновлениями, если вас интересует практический аспект машинного обучения.

Возможно, вас заинтересуют некоторые из моих других статей о Pandas:

Больше можно найти на моем Github.