Как выполнить горячее кодирование столбца, который существует в нескольких кадрах данных pandas?

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

Первое, что я попробовал, — это объединить все десять фреймов данных и выполнить таким образом одно горячее кодирование, но мой фрейм данных стал слишком большим, и ядро ​​моего ноутбука Jupyter продолжало умирать. Итак, теперь я решил попытаться подойти к каждому фрейму данных отдельно, но это создает для меня проблему, которую я объяснил выше, и мне было трудно найти решение. Вот пример того, что я ищу. Я бы хотел, чтобы Таблица 1 и Таблица 2 были одним горячим кодированием следующим образом.

Таблица 1

Команда год А 1 Б 1

Таблица 2

Команда год Б 2 С 2

Таблица 1. Горячее кодирование.

Команда год А Б С А 1 1 0 0 Б 1 0 1 0

Таблица 2. Горячее кодирование.

Команда год А Б С Б 2 0 1 0 С 2 0 0 1

По сути, вопрос в том, как мне получить столбец «C» в таблице 1 и столбец «A» в таблице 2, поскольку этих значений в этих таблицах не существует.

🤔 А знаете ли вы, что...
Синтаксис Python известен своей простотой и читаемостью.


1
69
1

Ответ:

Решено

Вам необходимо убедиться, что у вас есть коллекция всех уникальных команд в обоих DataFrames, и работать оттуда. Тогда вы можете либо…

A. проведите pandas.get_dummies по столбцу 'team', затем .reindex пропущенные команды в результат

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'team': ['a', 'b'], 'year': [1, 1]})
df2 = pd.DataFrame({'team': ['b', 'c'], 'year': [2, 2]})
teams = np.union1d(df1['team'].unique(), df2['team'].unique())

df1_encoded = pd.get_dummies(df1['team']).reindex(columns=teams, fill_value=False).astype(int)
df2_encoded = pd.get_dummies(df2['team']).reindex(columns=teams, fill_value=False).astype(int)

print(df1.join(df1_encoded))
#   team  year  a  b  c
# 0    a     1  1  0  0
# 1    b     1  0  1  0

print(df2.join(df2_encoded))
#   team  year  a  b  c
# 0    b     2  0  1  0
# 1    c     2  0  0  1

Б. преобразуйте столбцы команд в категориальные, pandas.get_dummies предоставит правильные результаты.

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'team': ['a', 'b'], 'year': [1, 1]})
df2 = pd.DataFrame({'team': ['b', 'c'], 'year': [2, 2]})

# Convert each Team column to a Categorical that share the same categories
TeamsDtype = pd.CategoricalDtype(
    np.union1d(df1['team'].unique(), df2['team'].unique())
)
df1['team'] = df1['team'].astype(TeamsDtype)
df2['team'] = df2['team'].astype(TeamsDtype)

# `get_dummies` *works* now with no extra contortion
df1_encoded = pd.get_dummies(df1['team']).astype(int)
df2_encoded = pd.get_dummies(df2['team']).astype(int)

print(df1.join(df1_encoded))
#   team  year  a  b  c
# 0    a     1  1  0  0
# 1    b     1  0  1  0

print(df2.join(df2_encoded))
#   team  year  a  b  c
# 0    b     2  0  1  0
# 1    c     2  0  0  1

Я рекомендую последний, категоричный подход, если вы собираетесь придерживаться колонки 'team'. в исходной форме, поскольку категориальная кодировка ускорит любую операцию сравнения и уменьшит объем памяти, занимаемой вашими данными.