Выполните однократное кодирование на фрейме данных Pandas для нескольких типов столбцов - PullRequest
0 голосов
/ 24 мая 2019

Итак, у меня есть кадр данных pandas, в котором определенные столбцы имеют значения списка типов и набор столбцов нечисловых и числовых данных.

Пример данных

   dst_address   dst_enforcement   fwd_count ...
1  1.2.3.4       [Any,core]        8
2  3.4.5.6       []                9
3  6.7.8.9       [Any]             10
4  8.10.3.2      [core]            0

До сих пор я смог узнать, какие столбцы не являются числовыми по этим двум строкам кода

col_groups = df.columns.to_series().groupby(df.dtypes).groups
non_numeric_cols = col_groups[np.dtype('O')]

Из всех этих нечисловых столбцов мне нужно выяснить, какие из них имеют список в качестве типа данных, и я хочу выполнить горячее кодирование для всех нечисловых столбцов (включая эти типы списков)

РЕДАКТИРОВАТЬ: мой ожидаемый результат для приведенного выше примера будет что-то вроде

   1.2.3.4 | 3.4.5.6 | 6.7.8.9 | 8.10.3.2 | empty | Any | core | fwd_count ...
1  1         0         0         0          0       1     1      8
2  0         1         0         0          1       0     0      9
3  0         0         1         0          0       1     0      10
4  0         0         0         1          0       0     1      0    

Ответы [ 3 ]

1 голос
/ 25 мая 2019

Я использую 3 шага следующим образом:

df['dst_enforcement'] = df.dst_enforcement.apply(lambda x: x if x else ['empty'])
dm1 = pd.get_dummies(df[df.columns.difference(['dst_enforcement'])], prefix='', prefix_sep='')
dm2 = df.dst_enforcement.str.join('-').str.get_dummies('-')
pd.concat([dm1, dm2], axis=1)

Out[1221]:
   fwd_count  1.2.3.4  3.4.5.6  6.7.8.9  8.10.3.2  Any  core  empty
1          8        1        0        0         0    1     1      0
2          9        0        1        0         0    0     0      1
3         10        0        0        1         0    1     0      0
4          0        0        0        0         1    0     1      0
1 голос
/ 24 мая 2019

Используйте unnesting, чтобы развернуть списки для разделения икр и вызвать pd.get_dummies():

df_new=unnesting(df,['dst_enforcement']).combine_first(df)
df_new.dst_enforcement=df_new.dst_enforcement.apply(lambda y: 'empty' if len(y)==0 else y)
m=pd.get_dummies(df_new,prefix='',prefix_sep='').groupby('fwd_count').first().reset_index()
print(m)

   fwd_count  1.2.3.4  3.4.5.6  6.7.8.9  8.10.3.2  Any  core  empty
0        0.0        0        0        0         1    0     1      0
1        8.0        1        0        0         0    1     0      0
2        9.0        0        1        0         0    0     0      1
3       10.0        0        0        1         0    1     0      0

Добавление функции, используемой для удобства:

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
             pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')
0 голосов
/ 24 мая 2019

Перейти на:

non_numeric_cols = col_groups[np.dtype('O')]

for non in non_numeric_cols:
    print(pd.get_dummies(df[non].apply(pd.Series)))

Выход:

   0_1.2.3.4  0_3.4.5.6  0_6.7.8.9  0_8.10.3.2
   0          1          0          0           0
   1          0          1          0           0
   2          0          0          1           0
   3          0          0          0           1

   0_Any  0_core  1_core
   0      1       0       1
   1      0       0       0
   2      1       0       0
   3      0       1       0

Если у вас нет ни «Any», ни «core», весь ряд - нули.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...