Во-первых, самый простой способ для одного горячего кодирования: использовать Sklearn.
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
Во-вторых, я не думаю, что использование pandas для одного горячего кодирования является простым (неподтвержденным, хотя)
Создание фиктивных переменных в pandas для python
Наконец, нужно ли вам для одного горячего кодирования? Одна горячая кодировка экспоненциально увеличивает количество функций, значительно увеличивая время выполнения любого классификатора или всего, что вы собираетесь запускать. Особенно, когда каждая категориальная функция имеет много уровней. Вместо этого вы можете делать фиктивное кодирование.
Использование фиктивного кодирования обычно работает хорошо, значительно меньше времени выполнения и сложности. Однажды мудрый профессор сказал мне: «Меньше больше».
Вот код для моей пользовательской функции кодирования, если вы хотите.
from sklearn.preprocessing import LabelEncoder
#Auto encodes any dataframe column of type category or object.
def dummyEncode(df):
columnsToEncode = list(df.select_dtypes(include=['category','object']))
le = LabelEncoder()
for feature in columnsToEncode:
try:
df[feature] = le.fit_transform(df[feature])
except:
print('Error encoding '+feature)
return df
EDIT: сравнение будет более четким:
Однострунная кодировка: convert n уровни до n-1 столбцов.
Index Animal Index cat mouse
1 dog 1 0 0
2 cat --> 2 1 0
3 mouse 3 0 1
Вы можете увидеть, как это взорвёт вашу память, если у вас много разных типов (или уровней) в вашей категориальной функции. Имейте в виду, что это всего лишь один столбец.
Dummy Coding:
Index Animal Index Animal
1 dog 1 0
2 cat --> 2 1
3 mouse 3 2
Вместо этого преобразуйте в числовые представления. Значительно экономит пространство для объектов за счет некоторой точности.
Используя пример функции data.frame и example (только +1 для всех значений)
A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))
wifi
# X1 X2 X3 X4 X5 X6 X7 X8 X9
#1 1 1 1 1 1 1 1 1 1
#2 2 2 2 2 2 2 2 2 2
#3 3 3 3 3 3 3 3 3 3
#4 4 4 4 4 4 4 4 4 4
data.frame(wifi[1:3], apply(wifi[4:9],2, A) )
#or
cbind(wifi[1:3], apply(wifi[4:9],2, A) )
# X1 X2 X3 X4 X5 X6 X7 X8 X9
#1 1 1 1 2 2 2 2 2 2
#2 2 2 2 3 3 3 3 3 3
#3 3 3 3 4 4 4 4 4 4
#4 4 4 4 5 5 5 5 5 5
Или даже:
data.frame(wifi[1:3], lapply(wifi[4:9], A) )
#or
cbind(wifi[1:3], lapply(wifi[4:9], A) )
# X1 X2 X3 X4 X5 X6 X7 X8 X9
#1 1 1 1 2 2 2 2 2 2
#2 2 2 2 3 3 3 3 3 3
#3 3 3 3 4 4 4 4 4 4
#4 4 4 4 5 5 5 5 5 5
Как уже упоминалось, вы просто хотите, чтобы стандартная функция R apply
применялась к столбцам (MARGIN=2
):
wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A)
Или, если коротко:
wifi[,4:9] <- apply(wifi[,4:9], 2, A)
Это обновляет столбцы 4: 9 на месте с помощью функции A()
. Предположим теперь, что na.rm
является аргументом A()
, который, вероятно, должен быть. Мы можем передать na.rm=T
, чтобы удалить значения NA из вычисления следующим образом:
wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A, na.rm=T)
То же самое верно для любых других аргументов, которые вы хотите передать своей пользовательской функции.
lapply
, вероятно, является лучшим выбором, чем apply
здесь, так как применяют первые коллажи вашего файла data.frame к массиву, что означает, что все столбцы должны иметь один и тот же тип. В зависимости от вашего контекста это может иметь непреднамеренные последствия.
Шаблон:
df[cols] <- lapply(df[cols], FUN)
Вектор «cols» может быть переменными именами или индексами. Я предпочитаю использовать имена, когда это возможно (он устойчив к переупорядочению столбцов). Таким образом, в вашем случае это может быть:
wifi[4:9] <- lapply(wifi[4:9], A)
Пример использования имен столбцов:
wifi <- data.frame(A=1:4, B=runif(4), C=5:9)
wifi[c("B", "C")] <- lapply(wifi[c("B", "C")], function(x) -1 * x)
Я думаю, что вы хотите mapply. Вы можете применить функцию ко всем столбцам, а затем просто отказаться от столбцов, которые вы не хотите. Однако, если вы применяете разные функции для разных столбцов, кажется, что вы хотите mutate , из пакета dplyr.
$
, чтобы индексировать определенный столбец по имени вместо того, чтобы использовать[ : ]
для индексации по столбцу? Я попробовал добавить имена кодов:colnames(wifi) = c("a", "b", "c", "d", "e", "f", "g", "h" ,"i")
, но никаких попыток использовать lapply (wifi $ e, 2, X) не было. – santeko 21 April 2015 в 23:27wifi[c("a","b","c")]
, чтобы индексировать несколько столбцов по имени. – thelatemail 21 April 2015 в 23:35