Создание фиктивной переменной с использованием pandas или statsmodel для взаимодействия двух столбцов

У меня есть такой фрейм данных:

Index ID  Industry  years_spend       asset
6646  892         4            4  144.977037
2347  315        10            8  137.749138
7342  985         1            5  104.310217
137    18         5            5  156.593396
2840  381        11            2  229.538828
6579  883        11            1  171.380125
1776  235         4            7  217.734377
2691  361         1            2  148.865341
815   110        15            4  233.309491
2932  393        17            5  187.281724

Я хочу создать фиктивные переменные для отрасли X years_spend, которые создают переменную len(df.Industry.value_counts()) * len(df.years_spend.value_counts()), например, d_11_4 = 1 для всех строк, в которых промышленность == 1 и годы = 4, иначе d_11_4 = 0. Затем я могу использовать эти переменные для некоторых регрессионных работ.

Я знаю, что могу создавать группы, как я хочу, используя df.groupby(['Industry','years_spend']), и я знаю, что могу создать такую ​​переменную для одного столбца, используя синтаксис patsy в statsmodels:

import statsmodels.formula.api as smf

mod = smf.ols("income ~   C(Industry)", data=df).fit()

но если я хочу сделать с двумя столбцами, я получаю сообщение об ошибке: IndexError: tuple index out of range

Как я могу сделать это с пандами или с помощью какой-либо функции внутри статистических моделей?


person Mehdi    schedule 12.07.2017    source источник


Ответы (2)


Вы можете сделать что-то вроде этого, где вам нужно сначала создать вычисляемое поле, которое инкапсулирует Industry и years_spend:

df = pd.DataFrame({'Industry': [4, 3, 11, 4, 1, 1], 'years_spend': [4, 5, 8, 4, 4, 1]})
df['industry_years'] = df['Industry'].astype('str') + '_' + df['years_spend'].astype('str')  # this is the calculated field

Вот как выглядит df:

   Industry  years_spend industry_years
0         4            4            4_4
1         3            5            3_5
2        11            8           11_8
3         4            4            4_4
4         1            4            1_4
5         1            1            1_1

Теперь вы можете применить get_dummies:

df = pd.get_dummies(df, columns=['industry_years'])

Это даст вам то, что вы хотите :)

person Scratch'N'Purr    schedule 12.07.2017
comment
спасибо, я понял это, используя циклы for и логическое индексирование, но вы показали мне более питонический способ. У вас есть идеи, как мне включить эти манекены в мою регрессию statsmodels? должен ли я использовать что-то вроде ` .join(['+industry{}'.format(x) for x in range(10) ])` или есть лучший способ. - person Mehdi; 12.07.2017
comment
Возможно, было бы неплохо создать столбец «industry_years», а затем использовать (income ~ C(industry)) , data = df) для создания манекенов для регрессии. - person Mehdi; 12.07.2017
comment
@Mehdi, извините, я не использовал statsmodels для моделирования, но я полагаю, что вы можете просто поместить все свои независимые переменные в переменную списка (используя df.columns и удалив столбец y), а затем построить строку, используя идею, которую вы дали ранее : "+".join(list_of_indep_vars), а затем создать свою модель с помощью "income ~ string_you_just_built". Конечно, это предполагает, что способ определения формулы регрессии в statsmodels — это y ~ x_1 + x_2 + x_3 ... x_n. - person Scratch'N'Purr; 13.07.2017

Используя синтаксис patsy, это просто:

import statsmodels.formula.api as smf

mod = smf.ols("income ~ C(Industry):C(years_spend)", data=df).fit()

Символ : означает «взаимодействие»; вы также можете обобщить это на взаимодействие более двух элементов (C(a):C(b):C(c)), взаимодействие между числовыми и категориальными значениями и т. д. Вы можете найти полезные документы.

person Nathaniel J. Smith    schedule 14.07.2017