Pivas Pivot Table to One_hot - PullRequest
       2

Pivas Pivot Table to One_hot

0 голосов
/ 26 ноября 2018

Я хочу, чтобы преобразовать панд df в One_hot pandas df.Лучший способ описать это может быть на примере:

Файл df, который у меня есть, выглядит следующим образом:

ID|DEV |STATE|
1 |DEV1|on
2 |DEV2|on
3 |DEV1|off
3 |DEV3|on
3 |DEV3|off

Я знаю, что неуникальный идентификатор не подходит, и я над ним работаю.

Затем я поворачиваю таблицу:

data.pivot_table(index='ID', columns=['DEV'], values='STATE', dropna=True, aggfunc='first')

Что приводит к следующему

ID|DEV1|DEV2|DEV3
1 |on  | NaN| NaN
2 | NaN| on | NaN
3 | off| NaN| on
4 | NaN| NaN| off

И теперь я хотел бы получить что-то вроде этого:

ID|DEV1.on|DEV1.off|DEV2.on|DEV3.on|DEV3.off
1 |     1 |       0|      0|      0|       0
2 |     0 |       0|      1|      0|       0
3 |     0 |       1|      0|      1|       0
4 |     0 |       0|      0|      0|       1

Я знаю, как объединить имена столбцов, но я не знаю, как получить стиль "one-hot".Может быть, это возможно с aggfunc?

Можете ли вы мне помочь?

Fabian

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Другой вариант:

df['new_col'] = df['DEV'] + '.' + df['STATE']
df1 = pd.get_dummies(df['new_col'])
df = pd.concat([df, df1], axis=1).drop(['DEV', 'STATE','new_col'], axis=1)
df = df.groupby("ID").sum().replace(0, np.nan)

Вывод:

    DEV1.off  DEV1.on  DEV2.on  DEV3.off  DEV3.on
ID                                               
1        NaN      1.0      NaN       NaN      NaN
2        NaN      NaN      1.0       NaN      NaN
3        1.0      NaN      NaN       1.0      1.0
0 голосов
/ 26 ноября 2018

Используйте get_dummies с объединенными столбцами с разделителем ., индексируйте по ID столбец по set_index и последний получите max по индексам:

df['join'] = df['DEV'] + '.' + df['STATE']
df = pd.get_dummies(df.set_index('ID')['join']).max(level=0)
print (df)
    DEV1.off  DEV1.on  DEV2.on  DEV3.off  DEV3.on
ID                                               
1          0        1        0         0        0
2          0        0        1         0        0
3          1        0        0         1        1

Другое решение с MultiIndex и изменением формы на unstack - но тогда необходимо swaplevel, sort_index и последнеерасплющить MultiIndex:

df = (pd.get_dummies(df.set_index(['ID','DEV'])['STATE'])
        .max(level=[0,1])
        .unstack(fill_value=0)
        .swaplevel(0,1, axis=1)
        .sort_index(axis=1))

df.columns = df.columns.map('.'.join)
print (df)
    DEV1.off  DEV1.on  DEV2.off  DEV2.on  DEV3.off  DEV3.on
ID                                                         
1          0        1         0        0         0        0
2          0        0         0        1         0        0
3          1        0         0        0         1        1
...