У меня есть pandas.DataFrame
:
| | col_1 | col_2 | col_3 | col_4 |
|:--|:------|:------|:------|:------|
| 0 | 1 | 2 | NaN | NaN |
| 1 | 3 | 4 | 5 | 6 |
| 2 | 2 | 6 | NaN | NaN |
Я должен преобразовать значения (1, 2, 3, 4, 5, 6) в столбцы и установить 1 для строк, если это значение в строке и 0 в противном случае:
| | 1 | 2 | 3 | 4 | 5 | 6 |
|:--|:--|:--|:--|:--|:--|:--|
| 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 1 | 1 | 1 | 1 |
| 2 | 0 | 1 | 0 | 0 | 0 | 1 |
pd.get_dummies
здесь не работает. Как я вижу, pd.get_dummies
не может one_hot кодировать через все значения в столбцах информационного кадра
Как я могу этого добиться?
3 ответа
Один подход с broadcasting
-
In [67]: df
Out[67]:
0 1 2 3
0 1.0 2.0 NaN NaN
1 3.0 4.0 5.0 6.0
2 2.0 6.0 NaN NaN
In [68]: constant_set = [1, 2, 3, 4, 5, 6]
In [69]: (df.values[:,:,None] == constant_set).any(1).astype(int)
Out[69]:
array([[1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1],
[0, 1, 0, 0, 0, 1]])
# Dataframe output
In [73]: out = (df.values[:,:,None] == constant_set).any(1).astype(int)
In [74]: pd.DataFrame(out, columns=constant_set)
Out[74]:
1 2 3 4 5 6
0 1 1 0 0 0 0
1 0 0 1 1 1 1
2 0 1 0 0 0 1
Еще один с учетом эффективности памяти -
idx = np.searchsorted(constant_set, a)
out = np.zeros((len(df),len(constant_set)),dtype=int)
flattend_idx = idx + out.shape[1]*np.arange(len(idx))[:,None]
out.flat[flattend_idx[idx<len(constant_set)]] = 1
Вы также можете использовать функцию get_dummies
следующим образом:
import numpy as np
import pandas as pd
# The definition of your dataframe
df = pd.DataFrame({'col_1': [1, 3, 2],
'col_2': [2, 4, 6],
'col_3': [np.NaN, 5, np.NaN],
'col_4': [np.NaN, 6, np.NaN]}, dtype=float)
# Get dummies where you leave out the prefix
# This will ensure that all columns of the same value will get the same column name
df = pd.get_dummies(df, columns=['col_1', 'col_2', 'col_3', 'col_4'], prefix='')
# Initialise your result
result = pd.DataFrame()
# Use the groupby method to group on column name
for column, data in df.groupby(level=0, axis=1):
# Merge data of same columns into one column
result[column] = data.max(axis=1)
Итак, что мы здесь делаем, так это применяем get_dummies ко всем столбцам, что приводит к чему-то вроде
_1.0 _2.0 _3.0 _2.0 _4.0 _6.0 _5.0 _6.0
0 1 1 0 1 0 0 0 0
1 0 0 1 0 1 1 1 1
2 0 1 0 1 0 1 0 1
Затем мы объединяем все столбцы с одинаковыми именами, чтобы получить желаемый результат
_1.0 _2.0 _3.0 _4.0 _5.0 _6.0
0 1 1 0 0 0 0
1 0 0 1 1 1 1
2 0 1 0 0 0 1
Другой подход с использованием pd.melt()
:
# Set it up.
import numpy as np; import pandas as pd;
df = pd.DataFrame({'col_1': [1, 3, 2],
'col_2': [2, 4, 6],
'col_3': [np.NaN, 5, np.NaN],
'col_4': [np.NaN, 6, np.NaN]}, dtype=float)
(pd.get_dummies( # Pandas' one-hot function
df.T.melt() # Flip DataFrame, then switch from wide to long format.
.set_index('variable')['value']) # "variable' is the row name (id) in your orig DataFrame.
.groupby('variable')
.sum()) # Coalesce same ids and add rows together.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.