get_dummies фрейма данных с неполными данными, используя pandas - PullRequest
1 голос
/ 08 апреля 2020

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

Например, давайте использовать следующий DataFrame:

>>> df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "x"], "c": ["h", "h", "i"]})
>>> df
   a  b  c
0  1  x  h
1  2  y  h
2  3  x  i

Столбец a имеет некатегориальные значения, но оба столбца b и c являются категориальными.

Теперь предположим, что столбец b может содержать категории x, y и z и столбец c категории h, i, j и k

>>> dummy_map = {"b": ["x", "y", "z"], "c": ["h", "i", "j", "k"]}

Я хочу закодировать это так что итоговый фрейм данных выглядит следующим образом:

>>> df_encoded
    a  b_x   b_y   b_z  c_h   c_i   c_j   c_k
0   1   1     0     0    1     0     0     0
1   2   0     1     0    1     0     0     0
2   3   1     0     0    0     1     0     0

Мое текущее решение выглядит следующим образом:

df_encoded = pd.get_dummies(df)
for k, v in dummy_map.items():
  for cat in v:
    name = k + "_" + cat
    if name not in result:
      df_encoded[name] = 0

Но мне кажется, что это немного неэффективно и не элегантно. Так есть ли лучшее решение для этого?

1 Ответ

1 голос
/ 08 апреля 2020

Используйте Index.union со значениями vae, сгенерированными при понимании списка, и f-string s и DataFrame.reindex:

c = [f'{k}_{x}' for k, v in dummy_map.items() for x in v]
print (c)
['b_x', 'b_y', 'b_z', 'c_h', 'c_i', 'c_j', 'c_k']

df_encoded = pd.get_dummies(df)

vals = df_encoded.columns.union(c, sort=False)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
   a  b_x  b_y  c_h  c_i  b_z  c_j  c_k
0  1    1    0    1    0    0    0    0
1  2    0    1    1    0    0    0    0
2  3    1    0    0    1    0    0    0

Если значения должны быть отсортированы в union:

df_encoded = pd.get_dummies(df)

vals = df_encoded.columns.union(c)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
   a  b_x  b_y  b_z  c_h  c_i  c_j  c_k
0  1    1    0    0    1    0    0    0
1  2    0    1    0    1    0    0    0
2  3    1    0    0    0    1    0    0
...