La verdad es que no sé como traducir el término “lookup table”, en fin, vamos al grano.
Supongamos que tengo un factor con 3 niveles o un vector de caracteres con 3 letras únicas y 20 valores.
set.seed(43)
vector_largo <- sample(c("a","b","c"), size = 20, replace = TRUE)
vector_largo
## [1] "b" "c" "a" "c" "a" "b" "c" "b" "a" "c" "b" "a" "b" "a" "b" "c" "a"
## [18] "a" "a" "a"
Y que en otro sitio tengo un vector “con nombres” dónde tengo el valor que asigno a “a”, “b” y “c”
vector_corto <- c(10,30,-99)
names(vector_corto) <- c("a","b","c")
vector_corto
## a b c
## 10 30 -99
El tema es sustituir en vector_largo
a, b y c por el valor que tienen en vector_corto
. Una forma fácil de hacerlo es usar los corchetes [
. Normalmente dentro de los corchetes solemos poner una condición o una lista de posiciones tipo
vector_largo[c(1,3,5)]
que devolvería las posiciones 1,3, y 5, pero veamos que pasa al hacer lo siguiente.
vector_corto[vector_largo]
## b c a c a b c b a c b a b a b c a a
## 30 -99 10 -99 10 30 -99 30 10 -99 30 10 30 10 30 -99 10 10
## a a
## 10 10
Al indexar sobre vector_corto
(que tiene names) y usar vector_largo
como índices obtenemos vector de longitud 20 y que sustituye a,b, c por su valor en la “lookup table” .
Es un truco viejuno pero útil.
Y en Python podría ser de esta forma (acepto correcciones).
import numpy as np
letras = ['a','b','c']
np.random.seed(13)
vector_largo = np.random.choice(letras, 20)
print(vector_largo)
## ['c' 'a' 'c' 'a' 'c' 'c' 'a' 'b' 'a' 'c' 'c' 'a' 'c' 'c' 'c' 'c' 'b' 'b'
## 'c' 'b']
lookup_table = {'a' : 2, 'b': 3, 'c' : 99}
Y usando las maravillosas listas por comprehensión
vector_largo_bis = [lookup_table[elemen]
for elemen in vector_largo
if elemen in lookup_table]
print(vector_largo_bis)
## [99, 2, 99, 2, 99, 99, 2, 3, 2, 99, 99, 2, 99, 99, 99, 99, 3, 3, 99, 3]
A mí me parece más elegante cómo se hace en R, pero también es probable que se pueda hacer de otra forma en Python.
Corrección en python
Un amable lector me comenta que me sobra el if
vector_largo_bis = [lookup_table[elemen]
for elemen in vector_largo ]
print(vector_largo_bis)
## [99, 2, 99, 2, 99, 99, 2, 3, 2, 99, 99, 2, 99, 99, 99, 99, 3, 3, 99, 3]
Aunque el if sería necesario si hay un elemento en vector_largo
que no está en lookup_table
.