У меня есть отображение, заданное в таблице ниже:быстрый способ классифицировать целочисленные данные
Input Output
<4 0
5 0.4
6 0.5
7 0.65
8 0.75
9 0.85
>=10 1
До сих пор я написал 3 версии:
k1 <- function(h) {
if (h <= 4) { k <- 0
} else if (h == 5) { k <- 0.4
} else if (h == 6) { k <- 0.5
} else if (h == 7) { k <- 0.65
} else if (h == 8) { k <- 0.75
} else if (h == 9) { k <- 0.85
} else if (h >= 10) { k <- 1}
return(k)
}
Второе:
k2 <- function(h) {
k <- 0
k[h == 5] <- 0.4
k[h == 6] <- 0.5
k[h == 7] <- 0.65
k[h == 8] <- 0.75
k[h == 9] <- 0.85
k[h >= 10] <- 1.0
return(k)
}
В-третьих:
k3 <- function(h) {
k <- cut(h, breaks=c(0, 5, 6, 7, 8, 9, Inf), labels=c(0, 0.5, 0.65, 0.75, 0.85, 1), right=FALSE)
return(k)
}
Мне нужна функция в двух разных сценариях. Во-первых, для оценки скалярного ввода и во-вторых, для оценки вектора значений.
Для скалярного ввода:
h <- 5
microbenchmark(k1(h), k2(h), k3(h))
Unit: microseconds
expr min lq mean median uq max neval
k1(h) 1.208 1.5110 2.38264 1.8125 2.114 15.698 100
k2(h) 4.529 5.5855 8.71286 6.3400 7.849 73.053 100
k3(h) 52.224 54.0360 71.74953 68.9785 79.393 304.286 100
Для вектора ввода:
h <- rep(5, 250)
microbenchmark(sapply(h, k1), k2(h), k3(h))
Unit: microseconds
expr min lq mean median uq max neval
sapply(h, k1) 595.592 617.327 641.8598 637.8535 654.9100 857.918 100
k2(h) 15.397 17.207 19.5470 18.1130 19.6225 49.508 100
k3(h) 110.486 116.070 131.3117 121.2020 140.6720 275.910 100
Таким образом, k1 является самым быстрым для скалярного входа и k2 для вектора входа.
Вы видите какую-либо возможность улучшить скорость? Я не могу поверить, что такой неуклюжий код if/else должен быть самым быстрым в скалярном случае. Кроме того, я хотел бы иметь единую функцию, а не две отдельные.
Почему это удивительно, что если/еще быстрее в скалярном случае? Он сразу возвращается после двух проверок и задания.Накладные расходы связаны с операциями векторизации, такими как присвоение подмножества –