Сообщить об ошибке.

Функция get_dummies() и from_dummies() модуля pandas в Python

Преобразование категориальной переменной в индикаторные (0/1) в pandas

Содержание:


Обзор функций pandas.get_dummies() и pandas.from_dummies()

Чтобы преобразовать категориальные переменные Series в "фиктивные" (0) или "индикаторные" (1), функция pandas.get_dummies() создает новый DataFrame со столбцами уникальных переменных и значениями, представляющими наличие этих переменных в строке.

>>> import pandas as pd
>>> df = pd.DataFrame({"key": list("bbacab"), "data1": range(6)})
>>> df
#   key  data1
# 0   b      0
# 1   b      1
# 2   a      2
# 3   c      3
# 4   a      4
# 5   b      5

>>> pd.get_dummies(df["key"])
#        a      b      c
# 0  False   True  False
# 1  False   True  False
# 2   True  False  False
# 3  False  False   True
# 4   True  False  False
# 5  False   True  False

# используем метод строки `Series.str.get_dummies()`
>>> df["key"].str.get_dummies()
#    a  b  c
# 0  0  1  0
# 1  0  1  0
# 2  1  0  0
# 3  0  0  1
# 4  1  0  0
# 5  0  1  0

Дополнительно смотрите материал "Методы строк объектов Series/Index в pandas"

Аргумент prefix добавляет префикс к именам столбцов, который полезен для объединения результата с исходным DataFrame:

>>> dummies = pd.get_dummies(df["key"], prefix="key")
>>> dummies
#    key_a  key_b  key_c
# 0  False   True  False
# 1  False   True  False
# 2   True  False  False
# 3  False  False   True
# 4   True  False  False
# 5  False   True  False

>>> df[["data1"]].join(dummies)
#    data1  key_a  key_b  key_c
# 0      0  False   True  False
# 1      1  False   True  False
# 2      2   True  False  False
# 3      3  False  False   True
# 4      4   True  False  False
# 5      5  False   True  False

Эта функция часто используется вместе с функциями дискретизации, такими как pandas.cut():

>>> import numpy as np
>>> values = np.random.randn(10)
>>> values
# array([ 0.33620661, -1.6352985 , -0.40552473,  0.13734276, -0.70195849,
#         0.97167785,  0.53875406, -1.09174529,  0.43937397, -1.61107065])
>>> bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
>>> pd.get_dummies(pd.cut(values, bins))
#    (0.0, 0.2]  (0.2, 0.4]  (0.4, 0.6]  (0.6, 0.8]  (0.8, 1.0]
# 0       False        True       False       False       False
# 1       False       False       False       False       False
# 2       False       False       False       False       False
# 3        True       False       False       False       False
# 4       False       False       False       False       False
# 5       False       False       False       False        True
# 6       False       False        True       False       False
# 7       False       False       False       False       False
# 8       False       False        True       False       False
# 9       False       False       False       False       False

Функция pandas.get_dummies() также принимает DataFrame. По умолчанию столбцы object, string, или categorical типа кодируются как фиктивные переменные, а другие столбцы не изменяются.

>>> df = pd.DataFrame({"A": ["a", "b", "a"], "B": ["c", "c", "b"], "C": [1, 2, 3]})
>>> pd.get_dummies(df)
#    C    A_a    A_b    B_b    B_c
# 0  1   True  False  False   True
# 1  2  False   True  False   True
# 2  3   True  False   True  False

Передача ключевого аргумента columns закодирует столбец любого типа.

>>> pd.get_dummies(df, columns=["A"])
#    B  C    A_a    A_b
# 0  c  1   True  False
# 1  c  2  False   True
# 2  b  3   True  False

Можно передать значения для аргументов prefix и prefix_sep. По умолчанию, в качестве префикса используется имя столбца, а символ подчеркивания _ - в качестве разделителя префикса. Указать prefix и prefix_sep можно 3 способами:

  • строка str: используется одно и то же значение для prefix или prefix_sep для каждого закодированного столбца.
  • список list: должен быть той же длины, что и количество кодируемых столбцов.
  • словарь dict: сопоставляет имя столбца с префиксом.
>>> simple = pd.get_dummies(df, prefix="new_prefix")
>>> simple
#    C  new_prefix_a  new_prefix_b  new_prefix_b  new_prefix_c
# 0  1          True         False         False          True
# 1  2         False          True         False          True
# 2  3          True         False          True         False

>>> from_list = pd.get_dummies(df, prefix=["from_A", "from_B"])
>>> from_list
#    C  from_A_a  from_A_b  from_B_b  from_B_c
# 0  1      True     False     False      True
# 1  2     False      True     False      True
# 2  3      True     False      True     False

>>> from_dict = pd.get_dummies(df, prefix={"B": "from_B", "A": "from_A"})
>>> from_dict
#    C  from_A_a  from_A_b  from_B_b  from_B_c
# 0  1      True     False     False      True
# 1  2     False      True     False      True
# 2  3      True     False      True     False

Чтобы избежать коллинеарности при передаче результатов в статистические модели, нужно указать drop_first=True.

>>> s = pd.Series(list("abcaa"))
>>> pd.get_dummies(s)
#        a      b      c
# 0   True  False  False
# 1  False   True  False
# 2  False  False   True
# 3   True  False  False
# 4   True  False  False

>>> pd.get_dummies(s, drop_first=True)
#        b      c
# 0  False  False
# 1   True  False
# 2  False   True
# 3  False  False
# 4  False  False

Если столбец содержит только один уровень, то в результате он будет опущен.

>>> df = pd.DataFrame({"A": list("aaaaa"), "B": list("ababc")})
>>> pd.get_dummies(df)
#     A_a    B_a    B_b    B_c
# 0  True   True  False  False
# 1  True  False   True  False
# 2  True   True  False  False
# 3  True  False   True  False
# 4  True  False  False   True

>>> pd.get_dummies(df, drop_first=True)
#      B_b    B_c
# 0  False  False
# 1   True  False
# 2  False  False
# 3   True  False
# 4  False   True

Значения можно привести к другому типу с помощью аргумента dtype.

>>> df = pd.DataFrame({"A": list("abc"), "B": [1.1, 2.2, 3.3]})
>>> pd.get_dummies(df, dtype=np.float32).dtypes
# B      float64
# A_a    float32
# A_b    float32
# A_c    float32
# dtype: object

Функция pandas.from_dummies() преобразует вывод pandas.get_dummies() обратно в Series категориальных значений из значений индикатора.

>>> df = pd.DataFrame({"prefix_a": [0, 1, 0], "prefix_b": [1, 0, 1]})
>>> df
#    prefix_a  prefix_b
# 0         0         1
# 1         1         0
# 2         0         1

>>> pd.from_dummies(df, sep="_")
#   prefix
# 0      b
# 1      a
# 2      b

Для данных с фиктивным кодированием требуется включить только k–1 категорий, в этом случае последняя категория является категорией по умолчанию. Категорию по умолчанию можно изменить с помощью аргумента default_category.

>>> df = pd.DataFrame({"prefix_a": [0, 1, 0]})
>>> df
#    prefix_a
# 0         0
# 1         1
# 2         0

>>> pd.from_dummies(df, sep="_", default_category="b")
#   prefix
# 0      b
# 1      a
# 2      b

pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None):

Функция pandas.get_dummies() преобразует категориальную переменную в 0/1 - "фиктивные/индикаторные" переменные.

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

Принимаемые аргументы:

  • data - исходные данные, из которых можно получить фиктивные показатели.

  • prefix=None - по умолчанию, в качестве префикса используется имя столбца.

    Указать prefix можно 3 способами:

    • строка str: используется одно и то же значение для каждого закодированного столбца.
    • список list: должен быть той же длины, что и количество кодируемых столбцов.
    • словарь dict: сопоставляет имя столбца и prefix.

  • prefix_sep='_' - разделитель при добавлении prefix.

    Указать prefix_sep можно 3 способами:

    • строка str: используется одно и то же значение для каждого закодированного столбца.
    • список list: должен быть той же длины, что и количество кодируемых столбцов.
    • словарь dict: сопоставляет имя столбца и prefix.

  • dummy_na=False - если ложные значения NaN игнорируются, то добавляет столбец для указания значений NaN.

  • columns=None - имена столбцов DataFrame, которые необходимо закодировать. Если столбцы имеют значение None, то будут преобразованы все столбцы с типом object, string или category.

  • sparse=False - должны ли столбцы с фиктивным кодированием поддерживаться pandas.arrays.SparseArray (True) или обычным массивом NumPy (False).

  • drop_first=False - следует ли удалить первый уровень k-1 из k макетов.

  • dtype=None - тип данных для новых столбцов. Допускается только один dtype.

Примеры использования pandas.get_dummies():

Кодируем Series:

>>> import pandas as pd
>>> s = pd.Series(list('abca'))
>>> s
# 0    a
# 1    b
# 2    c
# 3    a
# dtype: object

>>> pd.get_dummies(s)
#        a      b      c
# 0   True  False  False
# 1  False   True  False
# 2  False  False   True
# 3   True  False  False

Кодируем список:

>>> import numpy as np
>>> s1 = ['a', 'b', np.nan]
>>> pd.get_dummies(s1)
#        a      b
# 0   True  False
# 1  False   True
# 2  False  False

>>> pd.get_dummies(s1, dummy_na=True)
#        a      b    NaN
# 0   True  False  False
# 1  False   True  False
# 2  False  False   True

Кодируем DataFrame:

>>> df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['b', 'a', 'c'], 'C': [1, 2, 3]})
>>> df
#    A  B  C
# 0  a  b  1
# 1  b  a  2
# 2  a  c  3

>>> pd.get_dummies(df, prefix=['col1', 'col2'])
#    C  col1_a  col1_b  col2_a  col2_b  col2_c
# 0  1    True   False   False    True   False
# 1  2   False    True    True   False   False
# 2  3    True   False   False   False    True

Поведение аргумента drop_first=True:

>>> s2 = pd.Series(list('abcaa'))
>>> s2
# 0    a
# 1    b
# 2    c
# 3    a
# 4    a
# dtype: object

>>> pd.get_dummies(s2)
#        a      b      c
# 0   True  False  False
# 1  False   True  False
# 2  False  False   True
# 3   True  False  False
# 4   True  False  False

>>> pd.get_dummies(s2, drop_first=True)
#        b      c
# 0  False  False
# 1   True  False
# 2  False   True
# 3  False  False
# 4  False  False

Поведение аргумента dtype:

>>> pd.get_dummies(pd.Series(list('abc')), dtype=float)
#      a    b    c
# 0  1.0  0.0  0.0
# 1  0.0  1.0  0.0
# 2  0.0  0.0  1.0

pandas.from_dummies(data, sep=None, default_category=None):

Функция pandas.from_dummies() выполняет обратную операцию pandas.get_dummies().

Столбцы передаваемых фиктивных данных должны содержать только 1 и 0, или логические значения.

Принимаемые аргументы:

  • data - данные, которые содержат фиктивно закодированные переменные в виде 1/ 0 или True/False.
  • sep=None - разделитель, используемый в названиях столбцов фиктивных категорий, представляет собой символ, указывающий на отделение названий категорий от префиксов. Например, если имена столбцов 'prefix_A' и 'prefix_B', то можно убрать подчеркивание, указав sep = ’_’.
  • default_category=None - категория по умолчанию - это подразумеваемая категория, когда значение не имеет ни одной из перечисленных категорий. То есть, если все фиктивные значения в строке равны нулю. Может быть единственным значением для всех переменных или словарем dict, который будет напрямую сопоставлять категории по умолчанию с префиксом переменной.

Возможные исключения:

  • ValueError:

    • Когда входные данные DataFrame содержат значения NA
    • Когда входные данные DataFrame содержат имена столбцов с разделителями, которые не соответствуют разделителю, указанному с помощью sep.
    • Когда dict, передаваемый в default_category, не включает подразумеваемую категорию для каждого префикса.
    • Когда значению в data присвоено более одной категории.
    • Когда default_category=None и значению в data не назначена категория.
  • TypeError:

  • Когда входные данные не относятся к типу DataFrame.

  • Когда входные данные DataFrame содержат не фиктивные данные.

  • Когда переданный sep имеет неправильный тип данных.

  • Когда переданный default_category имеет неправильный тип данных.

Примеры использования pandas.from_dummies():

>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1, 0, 0, 1], "b": [0, 1, 0, 0], "c": [0, 0, 1, 0]})
>>> df
#    a  b  c
# 0  1  0  0
# 1  0  1  0
# 2  0  0  1
# 3  1  0  0

>>> pd.from_dummies(df)
# 0     a
# 1     b
# 2     c
# 3     a

Поведение аргумента sep:

df = pd.DataFrame({"col1_a": [1, 0, 1], "col1_b": [0, 1, 0],
                   "col2_a": [0, 1, 0], "col2_b": [1, 0, 0],
                   "col2_c": [0, 0, 1]})

>>> df
#       col1_a  col1_b  col2_a  col2_b  col2_c
# 0       1       0       0       1       0
# 1       0       1       1       0       0
# 2       1       0       0       0       1

>>> pd.from_dummies(df, sep="_")
#     col1    col2
# 0    a       b
# 1    b       a
# 2    a       c

Поведение аргумента default_category:

df = pd.DataFrame({"col1_a": [1, 0, 0], "col1_b": [0, 1, 0],
                   "col2_a": [0, 1, 0], "col2_b": [1, 0, 0],
                   "col2_c": [0, 0, 0]})

>>> df
#       col1_a  col1_b  col2_a  col2_b  col2_c
# 0       1       0       0       1       0
# 1       0       1       1       0       0
# 2       0       0       0       0       0

>>> pd.from_dummies(df, sep="_", default_category={"col1": "d", "col2": "e"})
#     col1    col2
# 0    a       b
# 1    b       a
# 2    d       e