Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
robertopucp
GitHub Repository: robertopucp/1eco35_2022_2
Path: blob/main/Lab8/regex_script_py.py
2714 views
1
# -*- coding: utf-8 -*-
2
"""
3
Created on Fri Oct 21 19:17:11 2022
4
5
@author: Roberto
6
"""
7
8
9
10
# import libraries
11
12
import pandas as pd
13
import numpy as np
14
import re # for regular expressions (REGEX)
15
import os # for directorio
16
import swifter # for parallel procesing
17
import unidecode # to drop tildes
18
from datetime import datetime # library for time
19
20
# !pip install swifter
21
# !pip install xlrd
22
23
user = os.getlogin() # Username
24
25
print(user)
26
27
# Set directorio
28
29
os.chdir(f"C:/Users/{user}/Documents/GitHub/1ECO35_2022_2/Lab8") # Set directorio
30
31
data = pd.read_excel("../data/Centro_salud/Centro_salud_mental.xls") # Subir base de datos
32
data
33
34
35
# from capital letters to lower
36
37
data.columns = map(str.lower, data.columns)
38
39
# map es el loop replacement que permite aplicar la función str.lower a cada elemento de la lista data.columns
40
41
42
#%% regex re.sub
43
44
45
"1.0 extraccción de texto"
46
47
# Extraer solo texto de una celda que contiene numero y texto
48
49
data['inst1'] = data['institución_ruc'].apply(lambda x: re.sub('[0-9]','',x))
50
51
# re.sub es de sustución
52
53
"[0-9]*: ninguno, uno o más digitos"
54
55
56
# Usando una librería de parallel procesing para que la computadora sea rápida
57
58
data['inst1'] = data['institución_ruc'].swifter.apply(lambda x: re.sub('[0-9]','',x))
59
data['inst1'] = data['institución_ruc'].swifter.apply(lambda x: re.sub('[0-9]','',x))
60
61
# Alternativas 1
62
63
data['inst2'] = data['institución_ruc'].apply(lambda x: re.sub('\d','',x))
64
65
66
# Alternativas 2
67
68
data['inst3'] = data['institución_ruc'].apply(lambda x: re.sub('[^a-zA-Z\s]','',x))
69
70
71
"2.0 extraccción de numeros"
72
73
74
# Alternativas 1
75
76
data['ruc1'] = data['institución_ruc'].apply(lambda x: re.sub('[a-zA-Z]','',x))
77
78
79
# Alternativas 2
80
81
data['ruc2'] = data['institución_ruc'].apply(lambda x: re.sub('[a-zA-Z\s]','',x))
82
83
# Alternativas 3
84
85
data['ruc3'] = data['institución_ruc'].apply(lambda x: re.sub('\D','',x))
86
87
#\D: caracteres diferetnes de digitos
88
89
# Alternativas 4
90
91
data['ruc4'] = data['institución_ruc'].apply(lambda x: re.sub('[^0-9]','',x))
92
93
# Sustituir caracteres diferentes a la fecha
94
95
data['fecha_apertura'] = data['fecha_apertura'].apply(lambda x: re.sub('(:00:00)|(!%&)|(00/00/00)','',x))
96
97
# | permite incluir varias opciones (disyuntivo 0 )
98
99
#%% re.findall
100
101
102
data['coordinates1'] = data['gps'].apply(lambda x: re.findall('-\d+.\d+,-\d+.\d+',x))
103
104
105
#Se obtiene error pues la variable gps celdas nan que son float y no string
106
107
# columa de string con nan, pero nan es float (en STATA sucede lo mismo)
108
109
110
data['coordinates2'] = data['gps'].apply(lambda x: re.findall('-\d+.\d+,-\d+.\d+', str(x) ) )
111
112
# se captura la presencia de más de un digito \d+, str(x): transforma a texto cada fila de la columna
113
114
data['coordinates3'] = data['gps'].apply(lambda x: re.findall('-\d{1,2}.\d{1,3},-\d{2}.\d{1,4}', str(x) ))
115
116
# en lugar de indicar uno o más digitos con \d+, indicad la cantidad de digitos {1,2} de 1 a dos dígitos
117
# \d{1,4} de uno a cuatro digitos
118
119
data['coordinates4'] = data['gps'].apply(lambda x: re.findall('-\d*.\d*,-\d*.\d*', str(x)) )
120
121
#\d* ningun caso, uno + más casos
122
123
# Se retira los elementos dentro del output re.findall que es una lista
124
125
data['coordinates4']= data['coordinates4'].apply(lambda x: ''.join(x) )
126
127
data.info()
128
129
#%% re.search
130
131
132
# extracción del nombre de distrito y región
133
134
135
x = "AVENIDA LA PAZ CUADRA 3 LA PERLA CALLAO CALLAO distrito LA PERLA Region El CALLAO"
136
137
re.search('\.*[D/d]istrito\s([\w+\-\s]+)\s[R/r]egion\s([\w+\s]+)', x).group(1)
138
139
140
141
re.search('\.*[D/d]istrito\s([\w+\-\s]+)\s[R/r]egion\s([\w+\s]+)', x).group(2)
142
143
144
#\\.* : captura ninguna, una, o más de un caracter (cualquiera: espacios, letras, numeros, #!%&/())
145
# () permite capturar lo que me interesa. Puede acceder a cada grupo de interés mediante .group()
146
147
148
149
def dist_region(x):
150
151
output = re.search('\.*[D/d]istrito\s([\w+\-\s]*)\s[R/r]egion\s([\w+\s]*)',x)
152
153
return output.group(1), output.group(2)
154
155
156
data['distrito'] = data['dirección'].apply(lambda x: dist_region(x)[0])
157
158
159
data['region'] = data['dirección'].apply(lambda x: dist_region(x)[1])
160
161
162
# try and except cuando la celda tiene missing, simplemente me devolverá None
163
164
def phone(x):
165
166
try:
167
match = re.search('\.*\s(\d+\-\d+)', str(x))
168
169
return match.group(1)
170
171
# Si no encuentra un grupo por precencia de missing, se ejecuta la siguiente linea
172
173
except:
174
175
pass
176
177
data['phone'] = data['telefono'].apply(lambda x: phone(x))
178
179
data['phone'] = data['telefono'].apply(phone)
180
181
182
def reso_info(x):
183
184
match = re.search('DS-([0-9]+)-([0-9]+)\s([A-Z]+)', x)
185
186
return match.group(1), match.group(2), match.group(3)
187
188
189
data['code_res'] = data['resolucion'].apply(lambda x: reso_info(x)[0])
190
191
data['year_res'] = data['resolucion'].apply(lambda x: reso_info(x)[1])
192
193
data['entidad_res'] = data['resolucion'].apply(lambda x: reso_info(x)[2])
194
195
196
# Extracción del número telefónico
197
198
# Se coloca str(x) pues tenemos casos de float (nan)
199
# Colocamos * para el caso de las celdas vacias "". Cuando no se cumpla la condición me devuelva vacío ""
200
201
data['telefono1'] = data['telefono'].apply(lambda x: re.search("\.*([\d+\-\d+]*)$", str(x)).group(1))
202
203
204
data['telefono2'] = data['telefono'].apply(lambda x: re.search("\.*([...\-\d+]*)$", str(x)).group(1))
205
206
207
# extraer usuario de correo
208
209
correo = "[email protected]"
210
211
re.search("(\w+)\@\.*", correo).group(1)
212
213
214
#%% str.contains
215
216
data['Gob_regional_jur'] = np.where(data['institución_ruc'].str.contains('(^G)|(^R)', regex=True),1,0)
217
218
219
data['Minsa_jur'] = np.where(data['institución_ruc'].str.contains('^M', na = False),1,0)
220
221
# na = False no toma cuenta los missing
222
223
#%% Look around
224
225
# positive lookahead (?=)
226
227
228
data['apertura1'] = data['horario'].apply(lambda x: re.search("\d+\:\d+(?= am)",x).group())
229
230
# Solo debe colocarse group()
231
232
data['apertura2'] = data['horario'].apply(lambda x: re.search("[\d+\:]+(?= am)",x).group())
233
234
# positive lookbehind (?<=)
235
236
data['apertura3'] = data['horario'].apply(lambda x: re.search("(?<=apertura )[\d+\:]+",x).group())
237
238
239
# negative lookbehind (?<!)
240
241
242
data['cierre1'] = data['horario'].apply(lambda x: re.search("(?<!apertura )\d+\:\d+",x).group())
243
244
# negative lookbahead (?!)
245
246
data['pres_soles'] = data['presupuesto'].apply(lambda x: re.search("[\d*\,]+(?!\$)",x).group())
247
248
249
# \b: el string no está rodeado de letras o numeros
250
# \B: el string está rodeado de letras o numeros
251
252
data['pres_soles2'] = data['presupuesto'].apply(lambda x: re.findall("\w+\B[\d+\,]+\B",x)[0])
253
254
# retirar tildes del texto
255
256
data['presupuesto'] = data['presupuesto'].apply(lambda x: unidecode.unidecode(x))
257
258
259
data['presupuesto'] = data['presupuesto'].apply(unidecode.unidecode)
260
261
262
#%% Fechas
263
264
265
data['fecha_apertura_date'] = pd.to_datetime(data['fecha_apertura']
266
, dayfirst = True).dt.strftime('%d/%m/%Y')
267
268
# dayfirst = True se indica la columna fecha_apertura
269
# empieza con el día, luego con strftime se indica el formato dia/mes/año de la fecha
270
271
272
#%% Segunda aplicación, filtro de filas
273
274
junin = pd.read_excel("../data/Region_Junin.xlsx")
275
276
277
278
# select districs that contanis "AC"
279
280
junin.loc[ junin['District'].str.contains('AC') ]
281
282
283
junin.loc[junin['Place'].str.contains('pacha')]
284
285
286
junin.loc[junin['Place'].str.contains('pacha', flags = re.I)]
287
288
# re.I ignoring capital o lower letters
289
290
291
# Ignoring format re.I
292
293
junin.loc[junin['District'].str.contains('CIUDAD', flags = re.I)]
294
295
296
297
# If regex is False, then contains seeks "^hu" literaly
298
# # Beginning word with hu
299
300
junin.loc[junin['District'].str.contains('^hu', flags = re.I, na = False, regex = True)]
301
302
# regex True para identificar la expression regular, na = False para ignorar missing
303
304
# Ending word
305
306
junin.loc[junin['Place'].str.contains('ro$', flags = re.I, na = False, regex = True)]
307
308
309
junin.loc[junin['Place'].str.contains('ca$', flags = re.I, na = False, regex = True)]
310
311
# match : a , c , ac
312
313
newbase = junin.loc[junin['Place'].str.contains('^ac*', flags = re.I, na = False, regex = True)]
314
315
316
# match : ac (strict)
317
318
newbase = junin.loc[junin['Place'].str.contains('^ac+', flags = re.I, na = False, regex = True)]
319
320
# match a or c
321
322
newbase = junin.loc[junin['Place'].str.contains('^ac?', flags = re.I, na = False, regex = True)]
323
324
325
326