Transcripciones
1. Tráiler/avance de la clase: Hola a todos, Bienvenido al video de hoy, que está en consejos para escribir Python eficiente. Mi nombre es Lisa Simpson y soy científica de datos en una gran institución financiera. Pero cerca de cuatro años experiencia mi compañero Ray y yo realmente queríamos hacer estos videos porque notamos que hay una enorme brecha y las habilidades que
aprendes en
la escuela versus las que realmente necesitas en el mundo real. Por lo que todos nuestros videos estarán enfocados en conjuntos de datos
del mundo real, problemas del mundo real, y brindarte las habilidades que necesitas para resolver aquellas que no necesariamente enseñan en la escuela. Estamos súper emocionados de tenerte hoy y esperamos que te quedes por ahí. Hay toneladas de diferentes formas de
acelerar u optimizar tu código en Python. En este curso, me voy a centrar en
acelerar una tarea específica que probablemente
te encuentres haciendo mucho como científico de datos y no como bucear a través un DataFrame de Pandas y aplicar algunos transformaciones a datos de texto. Caminaremos por cuándo y por qué
optimizar tu código así como
pasaremos por seis formas diferentes recorrer un DataFrame de Pandas. Entonces tomaremos lo que hemos aprendido para aplicarlo a dos ejemplos de código que hemos refactorizado. Este tutorial está destinado a ser super principiante amigable. Usaremos Notebooks de Jupyter para que puedas ver todo el código que estoy escribiendo y ejecutarlo solo para ti. Y usaremos algunas bibliotecas de ciencia de datos muy populares como pandas y NLTK. El dato que usaremos para el curso de
hoy es el conjunto de datos de noticias AG. Se trata de un conjunto de datos de textos realmente popular que contiene más de un millón de artículos de noticias, sus títulos y sus descripciones, así
como categorías para cada uno de los artículos de noticias. En este curso, sólo estaremos centrándonos en el título del artículo de noticias. Además, aunque hay más un millón de puntos de datos en este conjunto de datos, sólo
vamos a tomar muestras unos pocos miles de registros sólo porque
no queremos que nuestro código se ejecute para siempre. Y con eso, empecemos.
2. Descripción y herramientas de el curso: De acuerdo, vamos a entrar en algunos consejos para escribir Python eficiente. Este curso está destinado a ser realmente amigable para principiantes. Estaremos usando un par de bibliotecas de ciencia de datos
muy populares, como pandas y NLTK o Natural Language Toolkit. Ahora no necesitas ser un experto en esas bibliotecas, pero sí ayuda tener un poco de familiaridad con ellas. Haré todo lo posible para explicar
las cosas a medida que avanzamos a lo largo del curso. He enumerado Python 3 bajo la sección de habilidades intermedias. Yo sí espero que ya tengas un
poco de familiaridad con Python. Pero si no lo hace, estaremos usando cuadernos Jupyter. Puedes seguir fácilmente y correr las celdas tú mismo. A lo largo de este curso, nos vamos a centrar en algún preprocesamiento de texto para nuestros artículos de noticias. En realidad tengo otro curso todo sobre el procesamiento del lenguaje natural en Python, estaremos usando varios de
los métodos que se imparten en ese curso. Por lo que recomendaría encarecidamente revisar ese fuera antes de ver este curso, así sucesivamente, este curso, estaremos usando PyCharm como nuestro entorno de desarrollo, pero realmente estaremos usando Jupyter Cuadernos para el desarrollo real. Pycharm solo nos permitirá hacer girar
un cuaderno Júpiter y hacer todas nuestras ediciones ahí dentro. Ahora puedes usar cualquier IDE que quieras. Simplemente prefiero PyCharm pero siéntete libre si usas Anaconda, podría ser arañas o VS Code o cualquier IDE lo hará. Además de los cuadernos PyCharm y Júpiter, nos estaremos centrando en las bibliotecas, pandas y Natural Language Toolkit, o NLTK.
3. Guía para optimizar: Por lo que la versión corta para
resumir este curso es que quizá no necesites hacer
optimización de inmediato. Te recomendaría correr unos
pasos antes de que realmente saltes
a optimizar tu código. En primer lugar, tu código
tiene que ejecutarse realmente para que puedas saber si
significa optimización. Entonces primero da el paso para
asegurarte de que tu código se ejecute, luego después de esa comprobación, pero obtienes la
salida que estás esperando porque a veces
tu código podría funcionar, pero los resultados que es producir
arte una vez que esperarías, una vez que lo tengas funcionando, y es la salida que lo
esperarías, entonces puedes empezar
a pensar, vale, es esta vista
que se está ejecutando actualmente aceptable para mí? Pero no todo se trata de ti. Si estás escribiendo este código para o
alguien más está consumiendo tu código
si quieres
asegurarte de que la velocidad sea
aceptable para eso, entonces si no hay personas
que estén usando tu código, podría tener usuarios que
indirectamente trabajan con tu código. Por lo que es importante hablar
con ellos sobre qué tipo de desempeño están
esperando de una determinada aplicación. Entonces, finalmente, después
de cubrir todo eso, estás potencialmente
listo para optimizar. Y cuando empieces a optimizar, vas a terminar repitiendo
el ciclo una y otra vez hasta cumplir con tus requisitos de
optimización. Modificé este tipo es ligeramente de la
documentación de Python. Así que siéntete libre de salir
a su página web y leer una tonelada más sobre
diferentes formas de optimizar. Y de nuevo, en este curso solo me
voy a
centrar en un subconjunto
realmente pequeño de cómo
puedes optimizar tu código Python.
4. Cuándo optimizar: Hemos hablado de
pasos para la optimización, pero ¿cuándo debería
optimizar realmente su código? He enumerado algunos ejemplos
diferentes aquí de cuándo es posible que
desee optimizar su código. Entonces hablemos a través de esos. Y una de las primeras
veces que podrías necesitar optimizar tu
código es cuando comienzas a trabajar con inteligencia artificial de big data durante más tiempo y trabajaste
con conjuntos de datos realmente pequeños. Escribí código que funcionaba
para esos conjuntos de datos. Entonces hubo
momentos en que empecé a escalar hasta conjuntos de datos más grandes que en realidad no pude
ejecutar mi código de manera eficiente
como lo tenía antes. Entonces, una vez que empieces a lidiar
con conjuntos de datos realmente grandes, quieres empezar a
intentar escribir tu código la
manera más óptima posible. Otra de las razones por las que
podría querer optimizar su código es si está
creando un componente reutilizable. Entonces digamos que estás trabajando en una determinada función
y te das
cuenta de que esa es
realmente
función útil para otras
personas de tu equipo. Tienes otras personas
que están haciendo exactamente lo mismo que tú, y podrían usar
esa función también. Ese podría ser un caso cuando
quieras optimizar tu código ya que más
personas lo están usando, y potencialmente
podrían estar ejecutándose, digamos, en un conjunto de datos más grande, entonces lo estás, mira
si vas adelante y hacer algo
de optimización para ellos. A continuación, es posible que
desee optimizar cuando se despliega
en la Nube, por lo que cada vez que empiece a
ejecutar cosas y diga AWS o Google Cloud, esos recursos no son gratuitos cuando se ejecuta cosas
en tu laptop local. No importa
lo lento que corran. Se trata básicamente de
cuánto tiempo estás dispuesto a
esperar a que completen la Nube. Tienes esta
complejidad añadida de
tener realmente que pagar por estos
recursos que estás usando. Entonces para no
tener tus cosas funcionando para siempre y
cargándote esta enorme campana, probablemente
quieras intentar
optimizar tus códigos, hazlo correr lo más rápido posible. Otro ejemplo de
cuándo podrías querer optimizar es cuando estás trabajando con usuarios externos
y tratando de
hacer posible la mejor experiencia para ellos. Digamos que has creado algún
tipo de modelo que hace una predicción en algún sitio web y el usuario tiene que
interactuar con ese modelo. Bueno, no quieren
estar esperando 10 horas para obtener una respuesta de ti para
cuál es tu predicción. Cuando tienes personas
que
dependen de algo que les
estás brindando, definitivamente
quieres
intentar optimizar tu código y hacerlo lo más rápido
posible. La optimización entra en
juego cada vez que intentas iterar rápidamente durante
una prueba de concepto. Y muchas veces cuando estás
trabajando en una prueba de concepto, tendrás muchos métodos
o técnicas
diferentes que
quieres comprobarlo. Y para poder probar
todos esos rápidamente, tu código tiene que ser optimizado. Por último, hay preocupaciones
éticas por un código que
se ejecuta realmente largo, incluso si tienes
tu código corriendo en la nube realmente
detrás de bambalinas, todo
eso se está ejecutando en un centro de
datos en algún lugar centros de datos tienen una
huella de carbono adscrita a ellos. Entonces, cuanto más tiempo se ejecute su código, más está aumentando
potencialmente esa huella
de
carbono del centro de datos. Entonces si estás consciente
del medio ambiente, esa podría ser también otra
razón para optimizar.
5. Descripción general de los métodos: Vamos a caminar por seis formas diferentes de
recorrer un DataFrame de Pandas. Vamos a empezar desde
la versión más lenta y trabajar nuestro camino hasta
la versión más rápida. Entonces vamos a estar
cubriendo bucles. Se planteó o tuplas,
una lista de comprensión, aplicar declaraciones y
vectorización con pandas series. Y si no
sabes lo
que significa nada de eso, está bien. Lo vamos a cubrir
todo en este curso hoy.
6. Carga un cuaderno de Jupyter: Está bien, así que he abierto mi IDE, que es PyCharm. Y lo que he hecho ya es solo crear un proyecto TA para esta clase. Tengo una carpeta para los datos, tengo mi Cuaderno Jupyter ahí dentro así como mi archivo
requirements.txt que tiene toda la biblioteca que estaremos usando en ella. Nuevamente, siéntase libre de usar cualquier entorno de desarrollo que funcione para usted. A lo mejor ese es el código VS, tal vez tú, esa araña realmente no importa. Simplemente vamos a usar esto a nuestros archivos y luego abrir un cuaderno de Júpiter desde aquí. Por lo que una de las mejores prácticas cada vez que
inicias un proyecto de Python es crear un entorno virtual e instalar todas tus bibliotecas allí. Ya he hecho esto, pero si no lo has hecho, lo que puedes hacer es solo abrir la terminal en PyCharm, ya
tengo mi configuración de entorno original y para instalar esos requisitos, lo que haría es solo hacer esta línea aquí. Entonces esto es pip install dash r, diciéndole que tenemos un archivo de requisitos y luego
estamos listando el nombre del archivo de requisitos. Entonces para poner nuestro cuaderno
Júpiter funcionamiento aquí en la terminal, solo
voy a escribir cuaderno jupyter. Y eso girará hacia arriba observando para nosotros interactúemos con el Cuaderno de Jupyter. Y así aquí está nuestro servidor web local con nuestro cuaderno Júpiter en él. Tengo este cuaderno de Python aquí. Debiste haber podido descargar esto más los datos y
el archivo de requisitos con las bibliotecas desde
la página web del curso. Voy a dar click en estos consejos para escribir libreta Python
eficiente para abrir eso y vamos a empezar. Muy bien, Así que ahora que tenemos nuestro cuaderno, empecemos a caminar por algún código. Este cuaderno está realmente destinado a ser una pieza independiente, y hay mucho de lo que cubrí en las diapositivas que contiene. Entonces siéntete libre en tu antitimed para leer todo este texto si
quieres como un poco de motivación por por por qué podríamos querer agilizar nuestro código. Poco ejemplo aquí al principio, también
tengo una nota aquí de cómo descargar PyCharm si no tienes un entorno de desarrollo y te gustaría tener uno, definitivamente recomiendo PyCharm. Puedes seguir este enlace aquí, saldrá a ese sitio y luego a partir de ahí
podrás seleccionar tu diferente sistema operativo. Y recomendaría ir con la versión de la comunidad porque tiene prácticamente todo lo que necesitarías en ella. Un pie estoy corriendo ahora mismo. Pero si quieres pagar algunas características más, sí
tienen una versión profesional también. Voy a saltarme algunas de las cosas que ya cubrí en las diapositivas y bajemos para aprender más sobre nuestro conjunto de datos.
7. Acerca de los datos: Estaremos trabajando con el conjunto de datos de noticias AG. Y este es realmente popular conjunto de datos de texto que tiene más un millón de artículos de noticias diferentes en él y contiene sus títulos de artículos de noticias, las descripciones, así como una columna de categoría para y lo que las diferentes categorías de los artículos noticiosos son. Saqué este conjunto de datos de Kaggle, así que sí me vinculé aquí si te gustaría ir y asustado, a pesar de que hay más de un millón de registros en conjunto de datos, sólo
vamos a estar usando una muestra de ellos. Entonces lo que estoy haciendo aquí es cargar y un par de bibliotecas que necesitaremos. Estoy leyendo en este train.py CSV. Este va a ser nuestro conjunto de datos con el que trabajaremos. Y entonces estoy tomando muestras de 5000 registros de ahí. Este estado aleatorio como solo un número aleatorio que permite reproducir mis resultados. Entonces sigamos adelante y ejecutemos esto y echemos un vistazo a nuestro conjunto de datos. Por lo que puedes ver aquí que
tenemos esta columna de índice de clases. Esto cuenta con una categoría para cada uno de los artículos de noticias. Tenemos el título del artículo de noticias así
como una descripción del artículo de noticias. En esta clase, realmente vamos a estar
enfocados sólo en manipular el título
del artículo de noticias que también podrías usar este conjunto de datos para un
problema de clasificación si quieres hacer.
8. Bucle for: Por lo que hoy vamos a estar buceando sobre un marco de datos. Y hay muchas maneras diferentes en las que puedes hacer eso. Una de las cosas realmente grandes que me encanta de Python o realmente cualquier lenguaje de programación, es que no hay una sola manera correcta de resolver un problema. Se puede tener dos personas tienden a ser audaces. A 20 personas todas les llegan soluciones
completamente diferentes que resuelven el mismo problema. Entonces vamos a caminar por seis formas diferentes de recorrer un DataFrame de Pandas. Y vamos a estar calculando el número de personajes que están en el título de cada uno de estos artículos de noticias. Y veremos cómo el rendimiento impacta a cada uno de estos métodos. Por lo que empezaremos con uno de los métodos más lentos. Y esto es solo un bucle básico de cuatro para que se usan bucles, son realmente a través de muchos idiomas diferentes y son una de las formas más básicas que puedes iterar sobre datos. Entonces si has aprendido otro lenguaje de programación antes de Python, probablemente
hayas hecho cuatro bucles antes. De lo que esto termina luciendo en Python es el seguimiento para cada uno de estos ejemplos, voy a iniciar un temporizador para rastrear cuánto tiempo tardan los ejemplos. Tan solo tenga en cuenta que dependiendo los recursos que tenga en su máquina, podría obtener respuestas ligeramente diferentes a las que yo. Incluso si lo ejecutas varias veces, probablemente
obtendrás respuestas diferentes. Y así utilizamos la biblioteca del tiempo para obtener nuestra hora de inicio. Y luego también en nuestro
tiempo de final también y calculamos cuánto tiempo tarda. Entonces para recorrer un DataFrame con un for-loop, lo que primero hacemos, lista
temporal para contener todo el número de caracteres en el título por el que vamos a estar buceando. El sintaxis es similar a un montón de lenguajes diferentes. Vamos a decir que para I en rango 0 a través de la longitud del DataFrame, todo lo que está haciendo es obtener cuántas filas hay en el DataFrame, averiguando cuál es el número máximo que necesitamos iterar más. Y estamos usando yo como esta variable de índice. Entonces dentro del bucle for, lo que estamos haciendo es tomar este DataFrame, lo estamos haciendo. Yo lo encierro. Y esta es una forma de indexar diferentes piezas de un DataFrame de Pandas y acceder a diferentes partes de ellas estaban usando nuestra variable desde antes para decir en qué elemento estamos en el DataFrame. Y entonces también estaban extrayendo el título de esa columna y para obtener el número de personajes, todo lo que hacemos esta función Len para obtener la longitud de eso. Almacenamos eso en una variable y luego anexamos eso a nuestra lista que habíamos hecho temporalmente antes. Por lo que va a iterar sobre cada elemento en nuestro DataFrame, calcular la longitud, anexar eso a la lista, y luego finalmente asignamos esa lista a una nueva columna en nuestro DataFrame. Entonces veamos cuánto tiempo eso tarda en
unos 5000 registros y veamos el resultado. Entonces para mí eso tardó unos cinco segundos y dependiendo de otra vez, cómo son tus recursos en tu máquina, probablemente obtendrás una respuesta
diferente a la que yo hago, y eso está totalmente bien. Entonces estamos empezando con nuestro método más lento aquí y luego vamos a trabajar a la altura los métodos más eficientes. Hasta el momento nuestros resultados aquí, tenemos esta nueva columna en nuestro DataFrame llamada lengthen. Y eso tiene el número de caracteres que están en el título para cada uno de estos registros. Entonces solo estoy imprimiendo el primer virus oh, discos. Pero esto ha hecho esto para si tengo 1000 registros en total.
9. Iterrows: A continuación tenemos una función llamada hileras iter. Esta es una función que es específica de Pandas DataFrames y te permite iterar sobre un DataFrame como pares de series de índice. Y los pares de series de índices es la parte importante porque ahí es donde obtenemos algunas de nuestras ganancias de eficiencia aquí. Sintaxis, ¿por qué esto en realidad se ve realmente similar al bucle for que escribimos antes. En realidad sí comienza con un for-loop. Parece que usamos esta función de filas
ITER en lugar del rango para poder obtener automáticamente el número de filas que necesitan ser iteradas. No tenemos que hacer esas cosas de rango que hacíamos antes. No obstante, esta vez sí nombramos dos variables, una llamada índice y luego una fila de columna para que
podamos iterar sobre los índices. Y luego tenemos nuestra fila, y tomamos cada fila, obtenemos el título para esa fila, y luego obtenemos la longitud de esa. Y también anexamos que a nuestra lista es similar a nuestro ejemplo anterior. A continuación, asigne esa lista a una nueva columna llamada longitud. Entonces si ejecutamos esto, podemos ver cuánto tiempo
lleva eso y compararlo con el método original. Entonces parece que anteriormente
teníamos unos cinco segundos aquí y lo bajamos a unos 1.5 segundos más o menos. Y se puede ver en nuestro DataFrame aquí
obtenemos exactamente la misma respuesta. Entonces solo encuentra un poco cambiando la forma en que escribimos nuestro código. Ganamos muchas eficiencias aquí, pero alertan spoiler, en realidad podemos hacerlo mejor que esto.
10. Itertuples: Entonces hay otra función en pandas llamada itertools y es realmente similar a la que surgió, pero en lugar de iterar sobre pares de series de índice, y esto realmente crea cada fila como una tuple con nombre. Y ahí es donde obtenemos las eficiencias aquí. La sintaxis sabia se ve similar al otro. No tenemos que definir un índice ya que es una tuple con nombre, solo
definimos nuestra variable de fila y luego llamamos a esta df.head son tuplas para recorrer cada elemento en nuestro DataFrame sin tener que
hacer nada de el material de rango que hicimos en nuestro primer ejemplo. Entonces esta vez tomamos cada fila, obtenemos el título, y luego tenemos la longitud de eso para anexar eso a nuestra lista y le asignamos una nueva columna. Entonces cuando ejecutamos eso y eso en realidad
termina consiguiendo un sub-segundo resultados si lo cual es toda una mejora desde donde empezamos que estás dando al respecto o tuplas es que sí
tienes que usar este accessor de punto. Por lo que rho dot título en lugar de esta notación corchetes que usamos con filas ITER. Y lo molesto de eso es que esto no funciona si tienes espacios en nombre de tus columnas. Entonces para usar este método, que yo recomendaría encarecidamente que
hagas sobre él surgió en tienes cambiar el nombre de todas tus columnas si tienen espacios para deshacerse de esto, lo cual puede ser un poco molesto de hacer. Pero una vez que has escrito y una vez que
tienes eso por el resto de tu vida. Entonces en el caso en que intentes decidir si debo usarlo surgió o entrar tuplas fuera. Siempre recomendamos usarlo o tuplas para iterar sobre un marco de datos. Entonces una de las formas más rápidas que puedes.
11. Composición de la lista: Últimos tres métodos y voy a hablar de ello. Todos son bastante similares en velocidad. Y dependiendo de tu situación en la que te
encuentres, es posible que puedas usar una o quizá tengas que recogerla ahí arriba. Siguiente paso tenemos lista de comprensión. comprensión de listas solo ofrece una sintaxis más corta para crear una nueva lista
basada en valores de una lista existente. Y esto es específico de Python, creo So. Puede que no haya visto esto en otros idiomas antes que él. La sintaxis puede ser un poco confusa. Sé que cuando empecé a aprender listas de comprensiones, un poco me voló la cabeza. Realmente difícil de entender para mí. Que una vez que empiezas a verlos, unas cuantas veces, te pones realmente cómodo con ellos y luego empezaste a ver dónde puedes usarlos mucho en tu código. En realidad, es lo que me gusta hacer con una lista de comprensión es comenzar con el bucle for, leer ahí, y luego volver a lo que está pasando al inicio de la comprensión de lista. Entonces aquí estamos diciendo para x en nuestro título de columna DataFrame obtener la longitud de cada salida. Entonces estamos usando esto como lista y básicamente estamos diciendo que nuestra columna original era una lista y luego vamos a conseguir la longitud de esas y guardar eso como una nueva lista. Hacemos eso todo en una línea, así que es un poco más simple y
más compacto que estos otros métodos de los que hemos hablado hasta ahora. Y esto en realidad hace una lista para nosotros, así que no tenemos que anexar a la lista como hicimos y otros escenarios. Tomamos nuestra lista y luego asignamos eso a una nueva columna y podemos correr eso y ver cuánto tiempo lleva eso. Y de nuevo, esto es un poco más rápido. El final, el enfoque de tuplas ITER que hicimos antes. Pero a veces hay muchas cosas
complicadas que podrías necesitar
hacer para enviar mensajes de texto o cualquier dato con el que estés trabajando. Y no encaja
perfectamente en una lista de comprensión. Por lo que hay momentos en los que se puede usar esta y otras veces en las
que podría tener sentido utilizar el siguiente método que se aplica.
12. Apply: La mosca es específica de Pandas DataFrames. Y lo que hace es que te permite aplicar
una función a lo largo de un eje de un DataFrame. Y lo que eso significa es que puedo aplicar una función a todas mis columnas o a todas mis filas. Y la forma en que lo uso la mayoría de las veces es que voy a aplicar una función a todas las filas de mi DataFrame. A veces utilizas aplicar con sentencias
Lambda para crear funciones en línea. Entonces la forma en que esto se ve en Python es que
averiguamos qué columna queremos manipular. En este caso, es nuestro título de nuestro DataFrame. Nosotros sí punto aplicamos y luego hacemos esta lambda x con un colon y luego le damos qué función queremos hacer. Entonces en este caso solo estoy obteniendo la longitud de mi valor x es que va a obtener la longitud, cada título en nuestras filas DataFrame. Pero son realmente agradable acerca de las declaraciones aplica es que puedes escribir tu propia función personalizada, que veremos en realidad más adelante en un par de ejemplos que, y que en lugar de poner longitud aquí, solo llamas a tu función. Entonces es realmente agradable que puedas hacer algunas cosas más complejas en tu función. Y luego solo llama a la función aquí y aplica eso a cada fila en tu dataframe. Entonces si corremos eso a ese es super, súper rápido. Tenemos de nuevo, velocidades de sub-segundos aquí en 5000 registros. Y aplicar es una de mis formas
favoritas personales aplicar funciones a diferentes filas y a mi DataFrame. Ya que este es el que tiendo a escoger muchas veces
de todos los métodos de los que estamos hablando.
13. Vectorización con serie Pandas: Un método final para hacer un ciclo sobre un DataFrame es la vectorización con series de pandas. Este suele ser el enfoque más rápido que puedes obtener por hacer un ciclo en DataFrame. El complicado es que a veces no puedes conseguir tus datos en el formato correcto para trabajar con este método. Tenemos suerte de que en este caso, nos
haya dado un ejemplo donde esto no funciona. Podemos ver cómo funciona eso, pero a veces simplemente no puedes conseguir tus datos en el formato correcto para que esto funcione. Y así la vectorización en realidad permite aplicar diferentes operaciones en matrices enteras en lugar de cada individuo. Entonces para cada otro ejemplo por que hemos pasado hasta ahora, está iterando a través de cada fila en nuestro DataFrame. vectorización es tomar toda la columna y luego aplicar una transformación a la columna. Entonces de esta manera no tenemos que iterar sobre cada elemento en el DataFrame. Cómo se ve eso en la práctica aquí es que
tenemos nuestra columna que queremos manipular. Estoy obteniendo la versión de cadena de esa columna y luego obtengo la longitud de eso. Y cuando ejecutamos eso, y eso también es bastante rápido. Y sí veo aquí que está apareciendo como un poco más lento que el método de aplicación. Pero si ejecutas esto unas cuantas veces diferentes, obtendrás resultados diferentes. Entonces estos son todos sub segundos, así que estamos en bastante buena forma.
14. Ejemplo de Código 1: Lento: Entonces ahora tomemos todo esto que hemos aprendido aquí y pasemos por un par de ejemplos de código donde tenemos una versión más lenta del código y luego haremos algo de refactorización para que sea un poco más rápido. En este primer ejemplo, lo que vamos a hacer es limpiar el título de nuestros artículos de noticias por m minúscula y enviar mensajes de texto, o colocar ciertos tokens de un diccionario y luego quitar números y puntuaciones de los textos. Estos son pasos de preprocesamiento bastante estándar que normalmente harías si estás tratando con datos de texto. Y en realidad tengo un curso procesamiento de lenguaje
natural con Python que cubre varios de estos, así
como diferentes métodos para trabajar con el procesamiento del lenguaje natural. Entonces si estos son nuevos para ti, definitivamente
recomendaría revisar ese curso y aprender más sobre esos pasos ahí. Entonces en nuestra carpeta de datos, otra cosa que he incluido es un diccionario que he formado. Es solo un archivo CSV. Por lo que tenemos dos columnas de y para. De columna tiene un montón de abreviaturas y Reino Unido y NBA, nosotros y luego la dos columna tiene la versión totalmente expandida de esa abreviatura. ocasiones hay casos en los que quieres
expandirte a las abreviaturas que podrías tener en tu texto. Y esta es una forma de hacerlo. Estoy creando un diccionario tú mismo. Lo que vamos a hacer aquí es exactamente eso. Tenemos algunas abreviaturas en los títulos de nuestros artículos de noticias que queremos
ampliar a la versión completa de los mismos. Entonces para este primer ejemplo, vamos a empezar importando unas cuantas bibliotecas que vamos a estar usando. La mayoría de ellos solo están en la base Python y luego estaremos usando pandas para nuestros DataFrames como hemos estado usando en estos otros ejemplos. Entonces voy a
filtrar algunas advertencias que tenemos para que no desorden nuestras parcelas de salidas sin previo aviso, advertencias de filtro
stop está haciendo. Y entonces tenemos dos funciones aquí para preprocesar nuestros textos. El primero es una función de reemplazo de diccionario, y sólo estamos tomando aquí
el título del artículo de noticias. Entonces en esta función, cargamos en nuestro diccionario y lo guardamos como DataFrame, estamos creando una lista temporal para contener todos nuestros tokens expandidos o limpios. Y entonces lo que estamos haciendo es tomar nuestro título de nuestro artículo de noticias y dividirlo en espacios en blanco. Entonces eso nos consigue una lista de tokens que vamos a iterar sobre él. Entonces lo que estamos haciendo aquí en recorrer cada uno de nuestros tokens, comprobando si está en el diccionario donde lo cargamos. Si lo es, entonces vamos a anexar esa versión expandida a nuestra nueva lista. De lo contrario, basta con añadir el token anterior a partir de ahí. Lo que hacemos es unir a todos aquellos de nuevo juntos usando esta función join. Y simplemente separamos aquellos con espacios en blanco para que esta sea una sola cadena en lugar de una lista de tokens. Entonces todo eso es hacer algún reemplazo de diccionario. Y entonces tenemos aquí la segunda parte de nuestro preprocesamiento. Tomamos todo un marco de datos y esta función
y lo que hacemos en realidad es hacer algo de factorización, que fue uno de los métodos más rápidos que hablamos de ello, primero
somos minúsculas en nuestros textos con esta cadena más baja en toda la columna. Y entonces estamos sustituyendo dígitos por un espacio. Y luego tenemos un montón de puntuaciones diferentes que hemos enumerado aquí que vamos a reemplazar por espacios también. Entonces después de hacer todo eso, entonces realmente estamos usando una aplicación con un Lambda para llamar a esa función de reemplazo de diccionario y aplicarla a cada fila del DataFrame. Entonces estamos usando una mezcla aquí de algún método más lento así como algunos métodos rápidos. Y veremos aquí cuánto tiempo tardará esto en correr. Voy a cargar en esas funciones por las que acabo de hablar. Y luego aquí de la forma en
que en realidad lo llamamos así y función de título de preproceso, pasamos en todo nuestro DataFrame. Y luego recuerda que también aplica el
reemplazo del diccionario después de hacer la limpieza de nuestros tokens. Entonces si ejecutamos eso, veremos cuánto tiempo lleva eso. Y así en mi nota de máquina estoy ejecutando algún software de informes. Entonces esto probablemente es por lo que está tardando un poco más, pero esto tardó unos dos minutos en
ejecutarme en unos 5000 discos. Ahora si solo tienes 5 mil puntos de datos, entonces tal vez esto sea lo suficientemente bueno para ti. Nuevamente, puedes pensar en esos diferentes pasos para la optimización. Nos dieron la orina del pie, conseguimos los resultados correctos, y luego empezamos a pensar, bien, ¿esto tiene sentido para que funcione tanto tiempo en mi escenario? ¿ Estoy de acuerdo con eso? Entonces si solo estoy haciendo este análisis por un lado, probablemente eso esté bien para mí. Pero los problemas suelen entrar
cuando se empieza a tratar con conjuntos de datos realmente grandes. Nuevamente, este conjunto de datos tiene en total más de un millón de registros. Entonces si íbamos a hacer esto en todo
el conjunto de datos y podría tardar
demasiado para que seamos pacientes y esperáramos a nuestro alrededor. Por lo que podemos ver los resultados aquí tenemos esta nueva columna llamada, titulada Limpio. Y se puede ver aquí que lo hemos bajado en minúsculas. Tenemos algunas abreviaturas a las que me amplié. También nos deshicimos de los números y luego cualquiera de estas puntuaciones.
15. Ejemplo de código 2: refactorizado: Por lo que pasando a nuestra versión refactorizada de esto, tenemos nuestras mismas dos funciones, pero las hemos escrito un poco diferente. Entonces en lugar de cargar el diccionario cada vez que se ejecuta la función, que era lo que estábamos haciendo antes, en realidad vamos a cargarlo de una vez y luego pasarlo a nuestra función. Y luego también tomaremos el título
del artículo de noticias como hemos conseguido antes. Entonces aquí hemos condensado nuestra función original hacia abajo en león. Y esto es usar la funcionalidad de los diccionarios así como usar la comprensión de listas. Entonces puedes ver aquí abajo en nuestro código a continuación, cuando cargamos en nuestro diccionario, hacemos algo de formato para obtenerlo realmente en un formato de diccionario verdadero, mientras que antes era en realidad un DataFrame. Cuando hacemos eso, en realidad podemos usar este punto get funcionalidad para hacer eso. Busca para ver si la palabra existe en el diccionario. Si devuelve la versión completamente expandida, lo contrario devuelve la palabra original. Entonces cambiamos esa declaración entera if else en tan solo una sola línea aquí. Y entonces el resto de esto es sólo una lista de comprensión. Por lo que decimos para cada palabra en nuestro título punto split, realizar esta función. Esta división de punto de título solo obtiene una lista de los tokens que están en el título en función del espacio en blanco. Entonces, y luego recorremos cada uno de esos y luego realizamos esta función de diccionario. Por último, después de recuperar toda nuestra lista, nos sumamos de nuevo a eso como una sola cadena con la función join. A continuación tenemos nuestra función de preprocesamiento esta vez, en lugar de tomar un DataFrame completo y realizar operaciones en todo el DataFrame, solo
vamos a hacer esto en el título mismo y usar apply más adelante para aplicar esto. Entonces aquí tenemos las mismas pocas cosas que hacíamos antes. Estamos haciendo nuestra carcasa inferior con punto título inferior. Estás reemplazando dígitos esta vez por la biblioteca 3D, que es un poco más rápido que el enfoque que estábamos haciendo antes. Y entonces también estamos quitando toda puntuación aquí. Esto podría parecer un poco complicado, pero lo que estamos haciendo aquí es usar esta función Traducir, que es una función a la que puedes llamar en cadenas. Y luego usaríamos este str dot make trans para realizar algunas transformaciones. Aquí te darás cuenta de que tenemos puntuación de punto de cadena. La biblioteca de cuerdas es realmente agradable porque tiene una lista ya calculada para nosotros de todas las diferentes puntuaciones. Por lo que no tenemos que
enumerarlos todos como lo hicimos anteriormente. Por lo que en última instancia ambiciosa reemplaza toda puntuación con espacios en blanco. Y para ser honesto, no escribí esto yo mismo. Fui a ver a mi viejo amigo Google y encontré un post en Stack Overflow que estaba discutiendo diferentes formas de eliminar la puntuación y de qué manera era la más rápida. Encontré esto y solo copiarlo en este cuaderno y funciona muy bien para nuestra situación. Entonces eso es solo un rápido recordatorio de que
no tienes que saber optimizar todo es totalmente normal no sentirte libre de usar recursos como Google y StackOverflow para encontrar la forma más óptima de hacer algo. Ahora pasemos a
aplicar realmente en estas funciones y ver, verás aquí que estamos cargando nuestro diccionario una sola vez, originalmente, parecía que tenía sentido incluir eso con el ya que estaba relacionada con lo que estábamos haciendo, pero se estaba abriendo cada vez que se llamaba a esa función. No necesitamos hacer eso. Podemos simplemente cargarlo de una vez y obtenerlo en este formato de diccionario y luego pasarlo a nuestra función. Entonces para aplicar realmente estas funciones, estamos usando sentencias de aplicación con una función Lambda para llamar a esta función en línea. Aquí estamos tomando el título de la columna DataFrame. Estamos usando que aplicar con lambda x y luego llamamos a nuestra función de preprocesamiento. Ahora esta es la versión más avanzada de lo que hablaba antes, donde solo estábamos usando lambdas para llamar a la longitud del título. Esta vez en realidad estamos llamando a nuestra propia función personalizada, que es realmente agradable. Por lo general la forma en que me gusta hacer las cosas. Y así después de que tengamos nuestro texto preprocesado y lo siguiente que podemos hacer, llamar a nuestro reemplazo de diccionario y reemplazar todas esas instancias. Y así si corremos, esto es en realidad termina tomando menos de un segundo. Entonces pasamos de como dos minutos antes a alrededor de menos de un segundo aquí, lo cual es una locura solo por reescribir la forma en que escribimos nuestro código original. Ya verás aquí que he ahorrado esta nueva columna llamada título limpio versión dos. Y esto nos da exactamente el mismo resultado que obtuvimos antes.
16. Ejemplo de Código 2 - Lento: Por lo que pasamos a nuestro siguiente ejemplo. Digamos en este ejemplo queremos que cuente el número de fichas que están en el título del artículo de noticias. Pero para ser considerado un token, y vamos a tener unas condiciones que tienen que ser ciertas. Vamos a lematizar todos nuestros tokens para llevarlos a su forma de raíz. Y esas fichas lematizadas tienen a uno, ser mayor que un personaje para no ser una palabra stop. Y tres, estar en Natural Language Toolkit, vocabulario. Todo eso es una especie de nueva terminología para ti. Te recomendaría echar un vistazo a mi otro curso, procesamiento del lenguaje
natural en Python, donde nos sumergimos profundamente en lo que significa lematizar si parar palabras, qué es un vocabulario, toda esta terminología. Y así para implementar realmente estas reglas en Python, una forma en que podríamos hacerlo es importando unas cuantas bibliotecas que necesitamos, principalmente NLTK, que es Natural Language Toolkit y pandas. Por lo que NLTK tiene una lista de palabras stop y luego tiene sus propias lematizadas son que vamos a estar haciendo. Si estás ejecutando esto por primera vez,
tal vez necesites descargarlos y ya los he descargado, así que solo debería saltarse para mí cuando lo ejecuto. Tenemos esta función aquí llamada tokens de
recuento en vocab NLTK, y toma en una cadena dentro de la función que estamos llamando a nuestro WordNet lematizado desde NLTK. Y entonces estamos montando un contador. Estamos empezando con sólo un sencillo for loop aquí. Y otra vez estamos dividiendo nuestra cadena en espacios en blanco similares a nuestros otros ejemplos. Eso nos consigue una lista de tokens y vamos
a iterar sobre cada uno de esos tokens. Um, así que por cada ficha de
nuestra lista se van a lematizar el token. Y luego si la longitud de los tokens mayor que uno, no está en nuestras palabras stop y está en nuestro vocabulario, entonces aumente el contador y esto
devolverá el número de tokens que cumplan con este criterio. Carguemos estos. Se puede ver aquí que ya tengo descargados
estos artículos NLTK, pero podría tardar un segundo en descargarlos. A continuación, voy a eliminar el DataFrame con el que estábamos trabajando antes y en su lugar sólo muestreamos 50 registros porque alertan spoiler, este método lleva bastante tiempo. Y si estuviéramos haciendo 5000 discos para los que no me gustaría que nos sentáramos aquí. Por lo que nos ahorraremos algo de tiempo aquí y eliminaremos esos y recargaremos en un DataFrame con solo 50. Entonces para realmente aplicar esa función primero, vamos a aplicar el preprocesamiento que hicimos en nuestro primer ejemplo, así
como nuestro reemplazo de diccionario. Ahora, vamos a utilizar uno de los métodos más rápidos para aplicar esta función a nuestra columna limpia de título. Entonces veamos cuánto tiempo tarda eso en correr. Está bien, así que para mí esto tardó cerca de tres minutos, cual probablemente no es aceptable considerando que esto es sólo 50 lo registra. Entonces vamos a ver cuáles son los resultados aquí donde. Por lo que solo mirando los primeros cinco registros en nuestro DataFrame, puedes ver aquí que tenemos el número de tokens que cumplen con cierto criterio.
17. Ejemplo de código 2: refactorizado: Ahora a la
versión refactorizada de esto, realidad
vamos a deshacernos de la función que
escribimos antes y en
su lugar la usaremos de una manera
ligeramente diferente. Vamos a guardar las dos
primeras cosas que
hicimos de nuestro ejemplo anterior, preprocesamiento y haciendo nuestro reemplazo de
diccionario. Ahora lo que también hemos hecho aquí
es sacar esa palabra net lematizada y las palabras stop y vocabulario
de la función. Y sólo estamos llamando a esos
para que no se
recrean cada vez que se llama a
la función. Ahora aquí es donde sucede
la magia. Tenemos una
declaración de aplicación aquí donde la lambda con una
lista de comprensión. Descompongamos esto porque principio
podría parecer un poco
complicado. Entonces lo que normalmente me
gusta volver a hacer, cuando miro
las comprensiones de lista, Empieza donde está sucediendo el
for-loop, lee todo eso a la derecha, y luego vuelvo a lo que está pasando en el
lado izquierdo de eso. Entonces aquí estamos aplicando
esta operación a todo nuestro DataFrame en
nuestra columna limpia de título. Entonces en ese caso esa es nuestra salida. Entonces, para cada elemento que
estamos iterando, vamos a dividir
eso en el espacio en blanco. Entonces eso nos da
una lista de tokens similares a lo que hemos hecho
en ejemplos anteriores. Y luego vamos a revisar
algunas condiciones diferentes. Vamos a asegurarnos de que
el token lematizado sea mayor que un personaje. No está en nuestras palabras de
stop y
está en nuestro vocab de NLTK lo, si se cumplen todos esos criterios, vamos a
regresar justo ese token. Todo esto está envuelto en
una lista de comprensión. Recuerda, entonces
vamos a tener una lista de tokens
que cumplan con esos criterios. Y entonces sólo podemos conseguir
la longitud de la lista. Y eso debería
darnos el mismo
resultado que el que teníamos en
la diapositiva anterior. Entonces cuando corremos eso, volvemos a pasar de cerca a tres minutos abajo
a menos de un segundo, cual es impresionante verlo. Entonces en nuestro código aquí, verás que obtenemos
exactamente la
misma respuesta que hicimos para la versión
anterior. Y hemos ahorrado
tanto tiempo haciéndolo. Por lo que eso termina este curso en consejos para escribir Python
eficiente. Esperemos que
aprendas algunas técnicas para cómo recorrer en bucle a través de Pandas, DataFrames y también algo de
preprocesamiento en el camino. Y esto realmente solo rasca la superficie de lo que puedes hacer con la optimización de tu
código en Python, también, cuando comienzas a tratar
con datos agar, hay otras herramientas
y bibliotecas como Hadoop y VAX que pueden
ayudarte a lidiar con tus big data. Gracias por
seguir en esta lección, y espero
verlos en la siguiente.