Creo que muchos analistas y científicos de datos no dimensionan la importancia que tienen las expresiones regulares. No solo para identificar patrones y crear condiciones basadas en ellos (como en el código que hice algunos años Clasificación de correos y teléfonos usando Python) sino que simplifican muchísimo el arduo trabajo de limpieza de datos.
Estás están presentes en un gran número de lenguajes de programación como Python, R, SQL, Javascript, entre otros, debido a que es una sintaxis universal para identificar carácteres en una cadena de texto.
A continuación presento dos casos de uso donde el saber expresiones regulares simplifica muchísimo el trabajo:
Supongamos que tenemos los siguientes datos:
CP = [5010,5060,5280,7500,5601,8905]
Direccion = ['Calle Allende 7 Queretaro 7500', 'Boulevard 7 8905 Zacatenco', 'Ignacio 8 Zacatecas', '5060Franciso I Madero 87',
'Emeterio Arenas 5800 9 Toluca']
df = pd.DataFrame({'ID':[i for i in range(len(Direccion))],"Direccion":Direccion})
ID | Direccion |
---|---|
0 | Calle Allende 7 Queretaro 7500 |
1 | Boulevard 7 8905 Zacatenco |
2 | Ignacio 8 Zacatecas |
3 | 5060Franciso I Madero 87 |
4 | Emeterio Arenas 5800 9 Toluca |
Y se nos pide crear una nueva columna que contenga el CP de cada domicilio que siga lo siguiente:
- Si la dirección no tiene CP, la celda debe quedar vacía
- Si la dirección tiene un CP ajeno a los CP existentes (lista CP), la celda debe quedar vacía
ID | Direccion | CP |
---|---|---|
0 | Calle Allende 7 Queretaro 7500 | 7500 |
1 | Boulevard 7 8905 Zacatenco | 8905 |
2 | Ignacio 8 Zacatecas | NaN |
3 | 5060Franciso I Madero 87 | 5060 |
4 | Emeterio Arenas 5800 9 Toluca | NaN |
💡 Solución. Hay muchas soluciones posibles, pero usando expresiones regulares queda de la sig. manera:
df['CP'] = df.Direccion.str.extract(r"(\d{4})").astype(str)
df.loc[~df.CP.astype(float).isin(CP),'CP'] = np.nan
Tenemos el siguiente dataset con muchas frases:
Sent |
---|
The birch canoe slid on the smooth planks. |
Glue the sheet to the dark blue background. |
It's easy to tell the depth of a well. |
These days a chicken leg is a rare dish. |
Rice is often served in round bowls. |
The juice of lemons makes fine punch. |
The box was thrown beside the parked truck. |
Y deseamos conocer la distribución del total de palabras que existen
💡 Solución. Usando expresiones regulares queda de la sig. manera:
head(sents,7)
( sents_count <- sents %>% mutate(Sent = str_to_lower(str_remove_all(Sent,"[:punct:]"))) %>%
mutate(pals = str_count(Sent,"\\s+")+1) %>% count(pals) %>% arrange(desc(n)) )
pals | n |
---|---|
8 | 245 |
7 | 188 |
9 | 150 |
6 | 56 |
10 | 54 |
11 | 15 |
5 | 10 |
12 | 2 |
En el último ejemplo abuse de la sintaxis de R usando POSIX Character Classes pero podría usarse la expresión [^\w\s]. No obstante, el punto es ver como el código tanto en Python como R es más limpio, legible y mucho más rápido en ejecución.
Cuanto más sepas usar expresiones regulares más fácil y exhaustiva será la limpieza de datos 🥰.