0% encontró este documento útil (0 votos)
8 vistas3 páginas

Manual de Python

El 'Manual de Python aplicado a la Geología' es una guía diseñada para enseñar a estudiantes y profesionales de la geología a programar en Python, abordando conceptos fundamentales y su aplicación en problemas geológicos. El manual incluye secciones sobre tipos de datos, operaciones matemáticas, funciones, condicionales y bibliotecas útiles como Numpy y Matplotlib. Se requiere conocimiento básico en geología y matemáticas, y se puede interactuar con el contenido a través de plataformas como Google Colab o Jupyter Notebook.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
8 vistas3 páginas

Manual de Python

El 'Manual de Python aplicado a la Geología' es una guía diseñada para enseñar a estudiantes y profesionales de la geología a programar en Python, abordando conceptos fundamentales y su aplicación en problemas geológicos. El manual incluye secciones sobre tipos de datos, operaciones matemáticas, funciones, condicionales y bibliotecas útiles como Numpy y Matplotlib. Se requiere conocimiento básico en geología y matemáticas, y se puede interactuar con el contenido a través de plataformas como Google Colab o Jupyter Notebook.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Manual de Python aplicado a la Geología

Editado por: Kevin Alexander Gómez


Contacto: kevinalexandr19@[Link] | Linkedin | Github

Versión: 1.1 (Noviembre 2021)

Introducción
El Manual de Python aplicado a la Geología ha sido creado con la finalidad de facilitar el aprendizaje en Python para estudiantes y
profesionales en el campo de la Geología.

¿Qué voy a hacer?


Usando este manual, desarrollarás código en Python orientado al campo de la Geología.

¿Qué voy a aprender?


Aprenderás a desarrollar código usando Python.
Desarrollarás el pensamiento algorítmico.
Aprenderás a usar Python para solucionar problemas en Geología.

¿Qué voy a necesitar?


Este manual.

Nota: Este documento es un archivo de formato .ipynb y solo puedes interactuar con este notebook siguiendo
alguna de estas opciones:

A través de un navegador web, usando la aplicación de Google Colab .


Usando Binder , una aplicación web que permite ejecutar código arbitrario dentro de un entorno virtual (similar a
Google Colab ).
A través de un editor de código instalado en tu computadora, como por ejemplo: Jupyter Lab , Jupyter
Notebook o Visual Studio Code .\ Si no tienes instalado Python , puedes seguir las indicaciones del archivo
[Link] .

Conocimientos básicos en geología, estadística y álgebra lineal.


Perseverancia para aprender cada tema y creatividad para resolver problemas.

Índice

1. Tipos de datos e identificadores


2. Matemáticas en Python
3. Funciones input y print
4. Condicionales
5. Listas
6. Tuplas
7. Diccionarios
8. Bucles
9. Funciones
10. Clases y objetos
11. Numpy
12. Matplotlib
13. Pandas
14. Ejercicios

1. Tipos de datos e identificadores

Los datos son unidades de información, recogidas a través de la observación de un objeto o proceso.

En Python, existen diferentes formas de representar datos (tanto numéricos como no numéricos).\ Por ejemplo, si queremos representar el
número de muestras analizadas en un laboratorio, usaremos un integer:

Nota: para ejecutar un bloque con código (como el que está debajo), presiona shift + Enter .

In [1]: 25

25
Out[1]:

¿Qué es un integer? \ Un integer es un objeto en Python que representa a los números enteros.

Si queremos asignar este número a una variable, usaremos un identificador llamado muestras .\ El símbolo = se usa para indicar la
acción de asignarle nombre a un objeto:

In [2]: muestras = 25

Un identificador es un nombre usado para identificar un objeto dentro de Python.\ Nota: Los identificadores deben empezar con una
letra (de la A hasta la Z) o con un guión abajo _ .

Para observar el número de muestras debemos de llamar el identificador:

In [3]: muestras

25
Out[3]:

Ahora, ¿cómo representamos la concentración elemental de oro (Au) en una muestra?\ Para este caso, usaremos un float y lo asignaremos
a una variable llamada ley_au .\ Nota: Ten en cuenta que ley_au guarda el número mas no indica el tipo de unidad (que para este
caso, serían partes por millón o ppm).

In [4]: ley_au = 0.56

¿Qué es un float? \ Un float es un objeto en Python que representa números con fracción decimal.

Ahora ya sabemos como crear valores numéricos dentro de Python usando integers y floats.

¿Y qué pasa si queremos guardar un dato no numérico como por ejemplo, el nombre de una roca?, ¿qué tipo de dato debemos usar?\ En
ese caso, usaremos un string y lo asignaremos a una variable llamada roca :

In [5]: roca = "andesita"

¿Qué es un string? \ Un string es un objeto en Python que representa todo tipo de caracteres.\ Para crear un string
debemos encasillarlo usando comillas dobles ("") o simples ('').\

También podemos colocar frases dentro de un string:

In [6]: frase = "El presente es la clave del pasado"

In [7]: frase

'El presente es la clave del pasado'


Out[7]:

El último tipo de dato que debemos conocer es el lógico.

¿Qué es un dato lógico? \ Es un objeto en Python usado para representar el valor de verdad en una expresión.\ Los datos
lógicos pueden ser True (verdadero) o False (falso).

Por ejemplo, el resultado de comparar dos números:

In [8]: 12 > 5

True
Out[8]:

devuelve el valor True, pues la expresión es verdadera.

En conclusión, tenemos 4 tipos de datos fundamentales en Python: integer, float, string y lógico.

2. Matemáticas en Python

La lógica matemática es uno de los componentes principales detrás del funcionamiento de todo algoritmo.

2.1. Aritmética básica


Revisaremos las operaciones aritméticas básicas a través del siguiente ejemplo:

Una mina de cobre produjo durante 4 semanas las siguientes toneladas de concentrado: 910, 825, 1070, 940.\ Calcularemos el total
producido en un mes sumando las 4 cantidades y asignándolas a la variable total :

In [9]: total = 910 + 825 + 1070 + 940


total

3745
Out[9]:

En un mes (4 semanas), la mina produjo 3745 toneladas de concentrado.

También calcularemos el promedio de concentrado producido por la mina cada semana y la asignaremos a la variable llamada promedio :

In [10]: promedio = total / 4


promedio

936.25
Out[10]:

Ahora, calcularemos la ganancia producida por la mina teniendo en cuenta que el precio de concentrado por tonelada es de 5 dólares y el
costo de operación en ese mes fue de 10 000 dólares. Usaremos la siguiente fórmula:

ganancia = totalconcentrado × precioconcentrado − costooperacion

\ Asignaremos el precio de concentrado a la variable precio_concentrado y el costo de operación a la variable costo_operacion :

In [11]: precio_concentrado = 5
costo_operacion = 10000

La ganancia será asignada a la variable ganancia y también usaremos la variable total calculada anteriormente:

In [12]: ganancia = total * precio_concentrado - costo_operacion


ganancia

8725
Out[12]:

La ganancia de la mina en ese mes fue de 8725 dólares.

Ahora, calcularemos la varianza de la producción usando la siguiente fórmula:

2
∑(x−x̄)
2
s =
n−1

Donde:

s
2
: varianza\ x̄ : promedio\ x : dato\ n : número de datos

Recordemos que la producción semanal en la mina fue de 910, 825, 1070 y 940 toneladas. Por lo tanto n será igual a 4.

In [13]: n = 4

Calcularemos la diferencia entre la producción obtenida cada semana y el promedio semanal, y lo elevaremos al cuadrado:

In [14]: x1 = (910 - promedio)**2


x2 = (825 - promedio)**2
x3 = (1070 - promedio)**2
x4 = (940 - promedio)**2

Ahora sumaremos todas estas cantidades:

In [15]: sumatoria = x1 + x2 + x3 + x4

Y finalmente, calcularemos la varianza:

In [16]: varianza = sumatoria / (n - 1)


varianza

10322.916666666666
Out[16]:

2.2. Comparación entre valores


Usaremos comparadores para comparar dos valores y determinar la relación que existe entre ambos.

Tenemos las edades radiométricas de dos muestras A y B en millones de años:

In [17]: muestra_A = 100


muestra_B = 250

Podemos comparar las edades y obtener como resultado un dato de tipo lógico (True o False).\ Por ejemplo, evaluaremos si la muestra A
es más antigua que B:

In [18]: muestra_A > muestra_B

False
Out[18]:

Vemos que el resultado es falso, por lo tanto, la muestra A es más reciente que B:

In [19]: muestra_A < muestra_B

True
Out[19]:

También evaluaremos si la muestra B tiene una edad menor a 500 millones de años:

In [20]: muestra_B <= 500

True
Out[20]:

Ahora, evaluaremos si las muestras tienen la misma edad radiométrica:

In [21]: muestra_A == muestra_B

False
Out[21]:

Nuevamente obtenemos un resultado falso, es decir, las muestras tienen edades diferentes:

In [22]: muestra_A != muestra_B

True
Out[22]:

Por último, evaluaremos el valor de verdad de la siguiente frase: "La edad de la muestra A es mayor a 50 Ma y la edad de la muestra B
es menor a 200 Ma".\ Para eso, uniremos las comparaciones:

In [23]: (muestra_A > 50) and (muestra_B < 200)

False
Out[23]:

Podemos juntar varias comparaciones en una sola expresión usando and y or :

In [24]: (muestra_A == 50) or (muestra_B > muestra_A) and (muestra_A + 50 > muestra_B)

False
Out[24]:

2.3. Otros operadores en Python


Para obtener el residuo de dividir un número entre otro, usaremos el símbolo del porcentaje (%). Por ejemplo:

In [25]: 20 % 3

2
Out[25]:

Un número es par si el residuo de dividir dicho número entre 2 es 0:

In [26]: 12 % 2

0
Out[26]:

Para obtener el valor absoluto de un número, usaremos la función abs :

In [27]: abs(-7.5)

7.5
Out[27]:

3. Funciones input y print

Usaremos la función input para ingresar información dentro del sistema.\ Los datos ingresados usando esta función serán representados
como un string.

Por ejemplo, ingresaremos el nombre de una roca al sistema:

In [30]: input("Ingrese el nombre de una roca:")

'andesita'
Out[30]:

Por otro lado, tenemos la función print , que nos muestra información dentro del sistema.

Por ejemplo, mostraremos el nombre de la roca:

In [31]: roca = input("Ingrese el nombre de una roca:")

In [32]: print(roca)

andesita

La función print es comúnmente usada para establecer puntos de control en un algoritmo o para mostrarnos el resultado de alguna
tarea.

Por ejemplo, calcularemos el RQD de un tramo de testigo de perforación y usaremos print() para que nos muestre el valor del RQD.\ La
longitud de cada fragmento de testigo (en cm) es: 8, 12, 15, 9, 25, 19, 11, 4.

Empezaremos calculando la longitud total y la longitud de los fragmentos mayores a 10 cm:

In [33]: total = 8 + 12 + 15 + 9 + 25 + 19 + 11 + 4
mayor_10 = 12 + 15 + 25 + 19 + 11

Ahora, calcularemos el RQD dividiendo la suma entre el total:

In [34]: rqd = (mayor_10 / total) * 100

Ahora que ya tenemos calculado el RQD, lo uniremos a un string para formar una frase:

Usaremos la función str para transformar el valor del RQD en un string.

In [35]: resultado = "El RQD del tramo es de " + str(rqd) + " %"

Y usaremos print para observar el resultado:

In [36]: print(resultado)

El RQD del tramo es de 79.6116504854369 %

Como podemos ver, la función print devuelve un resultado en formato de lectura.\ Sin embargo, podemos mejorar un detalle adicional:
el número de decimales en el RQD. Para esto, tenemos dos opciones:

Opción 1: Usar la función round para redondear el valor del RQD:

La función round usa 2 parámetros: el valor a redondear y el número de decimales que quedarán luego del redondeo.

Redondeando el RQD:

In [37]: rqd_redondeado = round(rqd, 1)

Unimos los strings y mostramos el resultado:

In [38]: resultado = "El RQD del tramo es de " + str(rqd_redondeado) + " %"
print(resultado)

El RQD del tramo es de 79.6 %

Opción 2: Usar un f-string (string con formato literal), que contiene espacio reemplazable por variables:
Se debe agregar una f antes de empezar a escribir el string entre comillas.\ La variable se debe agregar dentro de un espacio
separado por llaves {} .\ Editaremos el formato del valor de la variable usando dos puntos : seguido del tipo de formato
(en este caso es .1f ).

Juntando la información:

In [39]: resultado = f"El RQD del tramo es de {rqd:.1f} %"

Mostramos el resultado:

In [40]: print(resultado)

El RQD del tramo es de 79.6 %

4. Condicionales

Para evaluar el camino que seguirá un algoritmo, estableceremos una condición que devolverá un valor lógico (True o False).\ El algoritmo
continuará por el camino que devuelva True .\ Las palabras reservadas usadas en una condicional son:

if : toda condicional inicia con esta palabra:


elif : en caso la condición principal o anterior no se cumpla, elif ejecutará el bloque de código que tenga asignado.
else : en caso ninguna condición se cumpla, else ejecutará el bloque de código que tenga asignado.

La estructura de una condicional es la siguiente:

if [condición]: \ [bloque de código] \ elif [condición]: \ [bloque de código] \ else: \ [bloque de código]

Por ejemplo, crearemos una condicional que evalúe si una roca es ígnea (y si se trata específicamente, de una andesita):

In [41]: roca = input("Ingrese el nombre de una roca:")

if roca == "andesita":
print("La andesita es una roca ígnea.")

La andesita es una roca ígnea.

El algoritmo devuelve la frase "La andesita es una roca ígnea" solo cuando la variable asignada a roca es "andesita".

Podemos agregar una opción adicional, en caso de que la roca no se trate de una andesita:

In [42]: roca = input("Ingrese el nombre de una roca:")

if roca == "andesita":
print("La andesita es una roca ígnea.")
else:
print("La roca no es una andesita.")

La roca no es una andesita.

Cuando la condición establecida no se cumple, el algoritmo devuelve la frase "La roca no es una andesita".

También podemos agregar otras opciones con los nombres de otras rocas ígneas:

In [43]: roca = input("Ingrese el nombre de una roca:")

if roca == "andesita":
print("La andesita es una roca ígnea.")
elif roca == "basalto":
print("El basalto es una roca ígnea.")
elif roca == "granito":
print("El granito es una roca ígnea.")
else:
print("La roca no es andesita, basalto o granito.")

La roca no es andesita, basalto o granito.

Ahora, agruparemos las condiciones en una sola expresión:

In [44]: roca = input("Ingrese el nombre de una roca:")

if (roca == "andesita") or (roca == "basalto") or (roca == "granito"):


print("La roca es ígnea.")
else:
print("La roca no es andesita, basalto o granito.")

La roca es ígnea.

5. Listas

Las listas son colecciones de datos modificables que se caracterizan por estar encerrados entre corchetes [] .

Por ejemplo, si tenemos una colección con los siguientes minerales: pirita, cuarzo, galena y calcopirita.\ Podemos agrupar los minerales en una lista
llamada minerales :

In [45]: minerales = ["pirita", "cuarzo", "galena", "calcopirita"]

Ahora, mostraremos el contenido de la lista:

In [46]: print(minerales)

['pirita', 'cuarzo', 'galena', 'calcopirita']

Si en la colección también tuvieramos esfalerita, ¿cómo la agregamos dentro de la lista?\ Para eso usaremos el método .append :

In [47]: [Link]("esfalerita")

print(minerales)

['pirita', 'cuarzo', 'galena', 'calcopirita', 'esfalerita']

¿Cómo agregaríamos los siguientes minerales en la lista: acantita y molibdenita?\ Para eso usaremos el método .extend :

In [48]: [Link](["acantita", "molibdenita"])

print(minerales)

['pirita', 'cuarzo', 'galena', 'calcopirita', 'esfalerita', 'acantita', 'molibdenita']

¿Cuántos tipos de minerales tengo en la colección?\ Para saber esto usaremos la función len :

In [49]: len(minerales)

7
Out[49]:

La colección contiene 7 tipos de minerales.

¿Cómo hago para seleccionar partes de la lista de minerales?\ A través de un método en Python conocido como slicing:

Para realizar slicing se sigue el siguiente formato: lista[inicio:final:paso] \ El orden número en Python empieza
desde 0, 1, 2, 3...

Para seleccionar todos los elementos de la lista:

In [50]: print(minerales[:])

['pirita', 'cuarzo', 'galena', 'calcopirita', 'esfalerita', 'acantita', 'molibdenita']

El primer elemento:

In [51]: print(minerales[0])

pirita

Los 3 primeros elementos:

In [52]: print(minerales[:3])

['pirita', 'cuarzo', 'galena']

El último elemento:

In [53]: print(minerales[-1])

molibdenita

Los últimos 3 elementos:

In [54]: print(minerales[-3:])

['esfalerita', 'acantita', 'molibdenita']

Por último, seleccionamos elementos de la lista de 2 en 2:

In [55]: print(minerales[::2])

['pirita', 'galena', 'esfalerita', 'molibdenita']

Imaginemos que ahora en la colección solo queda cuarzo, pirita, esfalerita y calcopirita. ¿Cómo removemos los otros minerales de la lista?\
Los removeremos usando el método .remove :

In [56]: [Link]("galena")
[Link]("acantita")
[Link]("molibdenita")

print(minerales)

['pirita', 'cuarzo', 'calcopirita', 'esfalerita']

Como siguiente ejemplo, tenemos las concentraciones de Au (en ppm) de varias muestras agrupadas en una lista:

In [57]: au_ppm = [10.1, 2.0, 0.4, 11.7, 6.3, 1.3, 0.1, 2.6, 8.1, 7.0]

Si queremos obtener el promedio de concentración de las muestras, dividiremos la suma de los elementos entre el total:

La suma de los elementos en una lista se puede calcular con la función sum .

In [58]: suma = sum(au_ppm)


total = len(au_ppm)

promedio = suma / total


promedio

4.96
Out[58]:

El promedio de concentración de oro en las muestras es de 4.96 ppm.

Ahora calcularemos los valores máximos y mínimos usando las funciones max y min :

In [59]: print(f"La concentración máxima de Au en las muestras es de {max(au_ppm)} ppm")

La concentración máxima de Au en las muestras es de 11.7 ppm


Por último, ordenaremos los elementos en la lista de menor a mayor usando la función sorted :

In [60]: sorted(au_ppm)

[0.1, 0.4, 1.3, 2.0, 2.6, 6.3, 7.0, 8.1, 10.1, 11.7]
Out[60]:

Y también ordenados de mayor a menor activando la opción reverse=True :

In [61]: sorted(au_ppm, reverse=True)

[11.7, 10.1, 8.1, 7.0, 6.3, 2.6, 2.0, 1.3, 0.4, 0.1]
Out[61]:

6. Tuplas

Las tuplas son colecciones de datos no modificables que se caracterizan por estar encerrados entre paréntesis () .

Por ejemplo, las coordenadas de un punto se pueden guardar en una tupla:

In [62]: punto = (10, 25, 15)

Calcularemos la distancia del punto a las coordenadas (5, 15, 4).\ Primero, asignaremos las coordenadas por separado:

In [63]: x, y, z = punto

Usaremos estas variables para calcular la distancia euclidiana:

In [64]: distancia = ((x - 5)**2 + (y - 15)**2 + (z - 4)**2)**(1/2)

print(f"La distancia del punto a la coordenada es de {distancia:.1f}")

La distancia del punto a la coordenada es de 15.7

7. Diccionarios

Los diccionarios son colecciones de datos modificables que se caracterizan por estar encerrados entre llaves {} .\ Además, cada elemento
en un diccionario está compuesto por una llave (key) y un valor (value).

Por ejemplo, crearemos un diccionario que contenga la composición mineralógica de una muestra:

In [65]: muestra = {"cuarzo": 35, "feldespato": 20, "plagioclasas": 30, "micas": 10}

Como podemos ver, cada elemento de la muestra está compuesto por una llave (nombre del mineral) y un valor (porcentaje en la
muestra):

In [66]: print(muestra)

{'cuarzo': 35, 'feldespato': 20, 'plagioclasas': 30, 'micas': 10}

Podemos seleccionar el porcentaje de un mineral de la siguiente forma:

In [67]: muestra["cuarzo"]

35
Out[67]:

Y también podemos modificar el valor de un porcentaje:

In [68]: muestra["cuarzo"] = 40

print(muestra)

{'cuarzo': 40, 'feldespato': 20, 'plagioclasas': 30, 'micas': 10}

Podemos obtener el porcentaje de un mineral incluso si no ha sido indicado previamente (por ejemplo, pirita).\ Para esto, usaremos la
función get e incluiremos un valor de porcentaje por defecto:

In [69]: [Link]("pirita", 0)

0
Out[69]:

Ahora, crearemos un nuevo elemento en el diccionario:

In [70]: muestra["pirita"] = 0

print(muestra)

{'cuarzo': 40, 'feldespato': 20, 'plagioclasas': 30, 'micas': 10, 'pirita': 0}

Si quiero obtener solamente las llaves del diccionario:

In [71]: [Link]()

dict_keys(['cuarzo', 'feldespato', 'plagioclasas', 'micas', 'pirita'])


Out[71]:

O solamente los valores:

In [72]: [Link]()

dict_values([40, 20, 30, 10, 0])


Out[72]:

También podemos seleccionar los elementos separados en tuplas:

In [73]: [Link]()

dict_items([('cuarzo', 40), ('feldespato', 20), ('plagioclasas', 30), ('micas', 10), ('pirita', 0)])
Out[73]:

7.1. Sets
Los sets o conjuntos son colecciones de datos desordenados que no pueden tener valores repetidos. Se encasillan entre llaves {} .

Por ejemplo, probaremos a crear un set y añadiendo minerales repetidos:

In [74]: minerales = {"pirita", "cuarzo", "galena", "cuarzo", "calcopirita", "cuarzo", "pirita"}

Observaremos que el set solamente guardó los elementos únicos:

In [75]: minerales

{'calcopirita', 'cuarzo', 'galena', 'pirita'}


Out[75]:

8. Bucles

Usaremos bucles si queremos realizar una tarea de manera repetitiva, iterativa, o cíclica.\ Existen dos tipos de bucles: definidos e
indefinidos.

8.1. Bucles definidos


Este tipo de bucle realiza una iteración por cada elemento dentro de un conjunto.\ Las palabras reservadas usadas en un bucle definido
son for e ìn y siguen la siguiente estructura:

for [elemento] in [conjunto]: \ [bloque de código]

Es importante indentar el bloque de código que seguirá luego de la primera línea del bucle.

Por ejemplo, crearemos un bucle que muestre los elementos de la función range :

Nota: La función range devuelve una secuencia de integers ordenados.

In [76]: for numero in range(5):


print(numero)

0
1
2
3
4

Si tengo una lista de minerales, podemos mostrar cada elemento de la lista usando un bucle:

In [77]: minerales = ["cuarzo", "biotita", "ortoclasa", "muscovita"]

for mineral in minerales:


print(mineral)

cuarzo
biotita
ortoclasa
muscovita

Podemos usar la función enumerate para enumerar cada elemento en el conjunto:

La función enumerate devuelve los elementos usando tuplas que contienen el número de orden de cada elemento.

In [78]: for mineral in enumerate(minerales):


print(mineral)

(0, 'cuarzo')
(1, 'biotita')
(2, 'ortoclasa')
(3, 'muscovita')
Por último, podemos usar la función zip para agrupar conjuntos de elementos en grupos de tuplas:

In [79]: minerales = ["pirita", "galena", "cuarzo"]


dureza = [6, 2, 7]

for grupo in zip(minerales, dureza):


print(grupo)

('pirita', 6)
('galena', 2)
('cuarzo', 7)
8.2. Bucles indefinidos
Este tipo de bucle permanece activo hasta que la condición principal deja de ser verdadera (True), por lo cual puede ser ejecutada de
manera indefinida.\ Para detener un bucle indefinido, debemos establecer una medida que termine con la ejecución del bucle.\ Las
palabras reservadas usadas en un bucle indefinido son:

while : repite el bucle mientras se mantenga la condición principal.


continue : termina la secuencia del bucle y empieza desde el inicio.
pass : continúa con la secuencia del bucle.
break : termina con el bucle y pasa a la siguiente línea de código fuera de este.

La estructura de un bucle indefinido es el siguiente:

while [condición]: \ [bloque de código]

Recuerda que es importante indentar el bloque de código dentro del bucle.

Por ejemplo, usaremos un bucle indefinido para crear un algoritmo que nos pida el nombre de una roca y solo termine de ejecutarse
cuando el nombre pertenezca a la lista indicada:

In [81]: rocas = ["andesita", "diorita", "basalto", "sienita"]

while True:
roca = input("Ingrese el nombre de la roca:")
if roca in rocas:
break
else:
print("El nombre ingresado no pertenece a la lista, intente denuevo.")

print(f"Bucle terminado, la roca ingresada es {roca}")

El nombre ingresado no pertenece a la lista, intente denuevo.

El nombre ingresado no pertenece a la lista, intente denuevo.

Bucle terminado, la roca ingresada es basalto

9. Funciones

Una función es una pieza de código que puede ser reutilizada en diferentes algoritmos. Para usar una función debemos llamarla por su
nombre.\ Para crear una función en Python debemos usar las siguientes palabras reservadas:

def : define el nombre de la función, le siguen los parámetros en paréntesis.


assert : evalúa una condición dentro de la función, de ser falsa, devolverá un AssertionError .
return : devuelve el resultado de la función.

La estructura para crear una función es la siguiente:

def [función](parámetros): \ [bloque de código] \ return [resultado]

Es importante tener en cuenta que la estructura de la función debe ir indentada luego de la primera línea.

Por ejemplo, crearemos una función llamada frase que devolverá un comentario:

Nota: En este primer ejemplo, usaremos print en vez de return para devolver el resultado.

In [82]: def frase():


print("Una roca es un agregado de minerales.")

Y ahora llamaremos la función:

In [83]: frase()

Una roca es un agregado de minerales.


Ahora crearemos una función un poco más compleja, esta vez usando un parámetro:

In [84]: def tipo_roca(tipo):


if tipo == "ígnea":
print("Es una roca ígnea.")
elif tipo == "sedimentaria":
print("Es una roca sedimentaria.")
elif tipo == "metamórfica":
print("Es una roca metamórfica.")

Un parámetro puede tener diferentes valores, representa una variable dentro de la función:

In [85]: tipo = "sedimentaria"


tipo_roca(tipo)

Es una roca sedimentaria.


También podemos llamar la función usando el string directamente:

In [86]: tipo_roca("metamórfica")

Es una roca metamórfica.

O también, señalando el valor del parámetro:

In [87]: tipo_roca(tipo="ígnea")

Es una roca ígnea.


Ahora que tenemos una mejor idea acerca de las funciones, crearemos una función llamada normalizar .\ Usando 3 números como
parámetros, la función normalizará estos valores con la finalidad de que su suma sea igual a 1.\ Por último, la función devolverá una tupla
conteniendo los 3 números normalizados:

In [88]: def normalizar(a, b, c):


suma = a + b + c
a /= suma
b /= suma
c /= suma
return (a, b, c)

Usaremos los valores 1, 5 y 10:

In [89]: normalizar(1, 5, 10)

(0.0625, 0.3125, 0.625)


Out[89]:

9.1. La función lambda


Si queremos definir una función breve y que solo será usada una sola vez, podemos usar la función lambda .\ Por ejemplo, definiremos la
sumatoria de los n primeros números naturales y la asignaremos a la variable sumatoria :

In [90]: sumatoria = lambda n: n*(n + 1)/2

Ahora, calcularemos la suma de los 20 primeros números naturales:

In [91]: sumatoria(20)

210.0
Out[91]:

9.2. Las funciones filter y map


Tenemos una lista con las concentraciones de Au de unas muestras en ppm:

In [92]: au = [3, 10, 5, 6, 8, 15, 24, 4, 2, 12, 7, 7, 5, 11, 21, 9, 10]

Para crear una lista con aquellas concentraciones de Au mayores a 10 ppm, usaremos la función filter :

In [93]: list(filter(lambda x: x > 10, au))

[15, 24, 12, 11, 21]


Out[93]:

Ahora, clasificaremos la lista de acuerdo a sus valores, "bajo" si es menor o igual a 10 ppm y "alto" si es mayor.\ Para esto, usaremos
la función map y asignaremos la nueva lista a una variable llamada valores :

In [94]: valores = list(map(lambda x: "alto" if x > 10 else "bajo", au))

In [95]: print(valores)

['bajo', 'bajo', 'bajo', 'bajo', 'bajo', 'alto', 'alto', 'bajo', 'bajo', 'alto', 'bajo', 'bajo', 'bajo', 'alt
o', 'alto', 'bajo', 'bajo']
Por último, para obtener el número de valores altos y bajos, usaremos el método .count .

Nota: .count solo se puede aplicar a listas y tuplas.

In [96]: [Link]("bajo")

12
Out[96]:

In [97]: [Link]("alto")

5
Out[97]:

10. Clases y objetos

Python es un lenguaje de programación orientado a objetos. \ Un objeto es una colección de datos y funciones que representan a una
entidad de la vida real. Cada objeto pertenece a una clase.\ Todo dentro de Python es tratado como un objeto: variables, funciones, listas,
tuplas, diccionarios, etc.\ La palabra reservada usada para crear una clase es class .

Por ejemplo, crearemos una clase que represente a una roca:

Nota: por convención, el nombre de una clase debe empezar con mayúscula.

In [98]: class Roca:


def __init__(self):
print("Has creado una roca dentro de Python!!")

La función __init__ representa el estado inicial del objeto, se ejecuta al mismo tiempo que el objeto es creado.\ El parámetro self es
una referencia del mismo objeto y se usa para establecer los métodos y atributos de la clase creada.

Un método es una función específica creada dentro de una clase.\ Un atributo es un valor específico almacenado dentro de
una clase.

Crearemos una instancia de la clase Roca :

In [99]: roca = Roca()

Has creado una roca dentro de Python!!


Ahora agregaremos algunos atributos:

In [100… class Roca:


def __init__(self, nombre, textura):
[Link] = nombre
[Link] = textura
print("Has creado una roca dentro de Python!!")

Y crearemos una nueva instancia:

In [101… roca = Roca("andesita", "afanítica")

Has creado una roca dentro de Python!!

Ahora observaremos sus atributos:

In [102… [Link]

'andesita'
Out[102…

In [103… [Link]

'afanítica'
Out[103…

Por último, crearemos un método llamado resumen que resuma los atributos de la roca en una frase:

In [104… class Roca:


def __init__(self, nombre, textura):
[Link] = nombre
[Link] = textura
print("Has creado una roca dentro de Python!!")
def resumen(self):
print(f"La roca es una {[Link]} de textura {[Link]}.")

Volvemos a crear la instancia:

In [105… roca = Roca("andesita", "afanítica")

Has creado una roca dentro de Python!!

Y usaremos el método para observar el resumen:

In [106… [Link]()

La roca es una andesita de textura afanítica.

11. Numpy

Usaremos esta librería para operar información en forma de vectores y matrices (álgebra lineal).

Empezaremos importando la librería:

Usaremos np como una referencia abreviada de la librería.\ Para usar una función de Numpy, debemos anteponer su
referencia (ejemplo: [Link] para calcular el logaritmo de un número).\ Para saber más sobre la importación de librerías,
revisar el Anexo 2.

In [107… import numpy as np

11.1. Vectores
Usaremos la función array y una lista para crear un vector:

In [108… vector = [Link]([1, 2, 3, 4, 5, 6])

In [109… print(vector)

[1 2 3 4 5 6]

Este vector contiene el mismo tipo de información en cada posición. Lo verificamos usando el atributo .dtype :

In [110… [Link]

dtype('int32')
Out[110…

Para transformar los valores del vector de integer a float, usaremos la función astype :

In [111… [Link](float)

array([1., 2., 3., 4., 5., 6.])


Out[111…

De manera similar a una lista o tupla, podemos seleccionar partes del vector haciendo slicing:

In [112… vector[0]

1
Out[112…

In [113… vector[2:5]

array([3, 4, 5])
Out[113…

También podemos reemplazar valores dentro del vector:

In [114… vector[-1] = 10

In [115… vector

array([ 1, 2, 3, 4, 5, 10])
Out[115…

Si establecemos una condición, obtendremos un vector con datos de tipo lógico:

In [116… vector > 2

array([False, False, True, True, True, True])


Out[116…

Podemos crear una copia del vector usando el método .copy :

In [117… copia = [Link]()

De esta forma, si modificamos un valor de la copia, el original permanecerá igual:

In [118… copia[0] = 0

In [119… print(vector)
print(copia)

[ 1 2 3 4 5 10]
[ 0 2 3 4 5 10]

11.2. Matrices
Usaremos la función array y una lista de listas para crear una matriz:

In [120… matriz = [Link]([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

In [121… print(matriz)

[[1 2 3]
[4 5 6]
[7 8 9]]

Para observa la forma de la matriz, usaremos el atributo .shape :

In [122… [Link]

(3, 3)
Out[122…

Podemos usar el método .reshape para cambiar la forma de la matriz:

In [123… [Link]((1, 9))

array([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
Out[123…

La transpuesta de una matriz se calcula usando el atributo .T :

In [124… print(matriz.T)

[[1 4 7]
[2 5 8]
[3 6 9]]
Para el siguiente ejemplo, tenemos dos matrices de 2 x 2, llamadas A y B:

In [125… A = [Link]([[1, 1], [1, 1]])


B = [Link]([[-1, 0], [0, -1]])

In [126… print(A)

[[1 1]
[1 1]]

In [127… print(B)

[[-1 0]
[ 0 -1]]
Podemos agrupar las matrices horizontalmente usando la función hstack :

In [128… [Link]([A, B])

array([[ 1, 1, -1, 0],


Out[128…
[ 1, 1, 0, -1]])

O verticalmente usando vstack :

In [129… [Link]([A, B])

array([[ 1, 1],
Out[129…
[ 1, 1],
[-1, 0],
[ 0, -1]])

También podemos usar la función concatenate para agruparlos de acuerdo a un eje (0 para vertical y 1 para horizontal).

In [130… [Link]([A, B], axis=0)

array([[ 1, 1],
Out[130…
[ 1, 1],
[-1, 0],
[ 0, -1]])

In [131… [Link]([A, B], axis=1)

array([[ 1, 1, -1, 0],


Out[131…
[ 1, 1, 0, -1]])

11.3. Álgebra lineal en Numpy


Tenemos dos vectores v y v :1 2

In [132… v1 = [Link]([1, 2, 3, 4])


v2 = [Link]([5, 6, 7, 8])

Podemos sumar y restar los vectores:

In [133… print(v1 + v2)

[ 6 8 10 12]

In [134… print(v1 - v2)

[-4 -4 -4 -4]

Multiplicar y dividirlos:

In [135… print(v1 * v2)

[ 5 12 21 32]

In [136… print(v1 / v2)

[0.2 0.33333333 0.42857143 0.5 ]

Calcular el producto escalar:

In [137… [Link](v1, v2)

70
Out[137…

También podemos calcular la suma de componentes, máximo, mínimo, media, varianza y desviación estándar de cada vector:

In [138… print(v1)

[1 2 3 4]

Suma
In [139… [Link]()

10
Out[139…

Máximo
In [140… [Link]()

4
Out[140…

Mínimo
In [141… [Link]()

1
Out[141…

Media
In [142… [Link]()

2.5
Out[142…

Varianza
In [143… [Link]()

1.25
Out[143…

Desviación estándar
In [144… [Link]()

1.118033988749895
Out[144…

Espacios lineales
Podemos crear espacios lineales usando la función arange :

In [145… [Link](1, 10, 1)

array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Out[145…

Y también usando linspace :

In [146… [Link](1, 10, 10)

array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
Out[146…

También podemos obtener números aleatorios usando el módulo random .\ El resultado puede ser un número, vector o matriz,
dependiendo de la forma dentro del paréntesis:

Por ejemplo, eligiremos un número aleatorio entre 0 y 1:

In [147… [Link]()

0.46075161087317984
Out[147…

Un número aleatorio de una distribución uniforme entre 0 y 5:

In [148… [Link](0, 5)

2.4711934365589894
Out[148…

Una matriz de 2 × 2 compuesta por números aleatorios de una distribución normal de media 0 y varianza 1

In [149… [Link](2, 2)

array([[-0.82086821, -0.67252129],
Out[149…
[ 0.30502665, -2.80741372]])

Por último, podemos establecer condiciones y devolver resultados en base a estos usando la función where .\ Por ejemplo,
reemplazaremos los valores de v mayores a 2 por el valor de 0 y los menores por el valor de 1:
1

In [150… [Link](v1 > 2, 0, 1)

array([1, 1, 0, 0])
Out[150…

12. Matplotlib

Esta librería es frecuentemente usada para elaborar gráficos en Python.

Empezaremos importando el módulo de figuras de matplotlib :

Usaremos plt como una referencia abreviada del módulo librería.\ También importaremos numpy .

In [151… import [Link] as plt


import numpy as np

Para los ejemplos de visualización, usaremos las siguientes funciones:

subplots : crea el espacio para una o varias figuras ordenadas en filas y columnas.
scatter : crea un diagrama de dispersión de puntos.
plot : crea una figura de líneas.
bar : crea un diagrama de barras.
hist : crea un histograma.
boxplot y violinplot : crean figuras que nos ayudan a visualizar la distribución de los datos.

Matplotlib es una librería fuertemente orientada a objetos, por lo tanto, usaremos identificadores.\ Para identificar las figuras, usaremos los
siguientes nombres:

fig : referencia el cuadro general de la figura.


axs o ax : referencian a las subfiguras creadas.

12.1. Diagrama de dispersión


In [152… x = [Link](1, 50)
y = 3*x + [Link](1, 50)

fig, ax = [Link](figsize=(6, 6))


[Link](x, y)
[Link]()

12.2. Figura de líneas


Usaremos además el método legend para agregar una leyenda y fontsize para modificar el tamaño de letra.

In [153… x = [Link](1, 11, 1)


y = x ** 2
z = x ** 3

fig, ax = [Link](figsize=(6, 6))


[Link](x, y, label="$x^{2}$")
[Link](x, z, label="$x^{3}$")

[Link](fontsize=16)
[Link]()

12.3. Diagrama de barras


In [154… x = [Link](["A", "B", "C"])
y = [Link](1, 100, (3,))

fig, ax = [Link](figsize=(6, 6))


[Link](x, y)
[Link]()

12.4. Histograma
In [155… x = [Link](10000,)

fig, ax = [Link](figsize=(6, 6))


[Link](x, bins=20)
[Link]()

12.5. Boxplot
In [156… x = [Link](10000,)
y = 2*x + 1
z = 2 - x

fig, ax = [Link](figsize=(6, 6))


[Link]([x, y, z])
[Link]()

12.6. Violinplot
In [157… x = [Link](10000,)
y = 2*x + 1
z = 2 - x

fig, ax = [Link](figsize=(6, 6))


[Link]([x, y, z])
[Link]()

13. Pandas

Esta librería es fundamental para el análisis, tratamiento y manipulación de datos estructurados (i.e. en filas y columnas).

Empezaremos importando la librería:

Usaremos pd como una referencia abreviada de la librería.\ También usaremos Numpy para generar información.

In [158… import pandas as pd


import numpy as np

13.1. Series
Empezaremos creando un objeto llamado Series , que es similar a un array de Numpy, excepto que llevan un índice (index):

In [159… [Link]([Link]((4,)))

0 0.135418
Out[159…
1 0.357604
2 0.813607
3 0.227746
dtype: float64

Los objetos de tipo Series representan unidades de filas y columnas.

También podemos crear una serie usando un diccionario:

In [160… rocas = [Link]({"A": "andesita", "B": "basalto", "C": "diorita", "D": "granito"})

In [161… rocas

A andesita
Out[161…
B basalto
C diorita
D granito
dtype: object

Podemos obtener el índice a través del atributo .index :


In [162… [Link]

Index(['A', 'B', 'C', 'D'], dtype='object')


Out[162…

Y los valores a través del atributo .values :

In [163… [Link]

array(['andesita', 'basalto', 'diorita', 'granito'], dtype=object)


Out[163…

Modificaremos el último valor de la serie rocas y la cambiaremos por andesita :

In [164… rocas[-1] = "andesita"


rocas

A andesita
Out[164…
B basalto
C diorita
D andesita
dtype: object

Por último, seleccionaremos el tercer elemento de la serie. Podemos hacer esto de dos formas:\ Usando el método iloc para ubicarlo a
partir del número de posición en el índice:

In [165… [Link][2]

'diorita'
Out[165…

O podemos usar el método loc para ubicarlo a partir del nombre asignado al índice:

In [166… [Link]["C"]

'diorita'
Out[166…

13.2. DataFrame
El otro tipo de objeto usado en Pandas es el DataFrame , que agrupa objetos de tipo Series en una tabla de filas y columnas.\ Cada fila
y columna del DataFrame puede llevar un nombre específico.

Como ejemplo, crearemos un DataFrame de 2 filas y 3 columnas usando un array y una lista de columnas A, B y C:

In [167… df = [Link]([Link]((2, 3)), columns=["A", "B", "C"])


df

Out[167… A B C

0 0.245161 0.753976 0.284377

1 0.367617 0.556403 0.093670

Podemos modificar los índices usando el atributo .index :

In [168… [Link] = ["Fila 1", "Fila 2"]


df

Out[168… A B C

Fila 1 0.245161 0.753976 0.284377

Fila 2 0.367617 0.556403 0.093670

Y por último, agregaremos una columna D con valores de tipo string:

In [169… df["D"] = ["abcdef", "ghijkl"]


df

Out[169… A B C D

Fila 1 0.245161 0.753976 0.284377 abcdef

Fila 2 0.367617 0.556403 0.093670 ghijkl

14. Ejercicios

14.1. Reporte de resultados en una mina


Una mina de Au obtuvo los siguientes resultados de producción para un determinado semestre:

Mes Au (onzas)

Enero 80

Febrero 105

Marzo 45

Abril 80

Mayo 75

Junio 125

Para obtener un reporte general de los resultados, se pide:

El total de onzas Au producidas en el semestre. Asignarlo a la variable total .


El costo de operación mensual de la mina fue de 40000 dólares. Asignarlo a la variable costo_operacion .
El precio de una onza de Au es de 1000 dólares. Asignarlo a la variable precio .
Usando estas tres variables, calcular la ganancia semestral de la mina asignándola a la variable ganancia .
Mostrar el resultado general usando la función print , usando el siguiente formato:\ "Durante el semestre, la mina produjo
___ onzas de Au con una ganancia total de ___ dólares"

In [170… total = 80 + 105 + 45 + 80 + 75 + 125


costo_operacion = 40000
precio = 1000

In [171… ganancia = total*precio - costo_operacion*6

In [172… print(f"Durante el semestre, la mina produjo {total} onzas de Au con una ganancia total de {ganancia} dólares")

Durante el semestre, la mina produjo 510 onzas de Au con una ganancia total de 270000 dólares

14.2. Riesgo geológico en una edificación


¿Cuál es la probabilidad de que un edificio sufra un terremoto de magnitud 7 teniendo en cuenta que su vida útil es de 100 años, y el
período de retorno del terremoto es de 500 años?. Usar la siguiente fórmula para el cálculo de la probabilidad de excedencia:

1 t
p = 1 − (1 − )
T

Donde:

p : probabilidad de excedencia
t : vida útil de la estructura
T : período de retorno

In [173… t = 100
T = 500
p = 1 - (1 - (1/T))**t

In [174… print(p)

0.18143319531157232

Respuesta: la probabilidad de que la edificación sufra un terremoto de magnitud 7 es de 18%.

14.3. Mineralogía de una muestra de roca (Parte 1)


Una muestra de granodiorita tiene la siguiente composición mineralógica: cuarzo (48%), plagioclasas (27%), feldespato (11%), biotita
(8%) , pirita (6%).\ Crear un diccionario en Python que guarde la mineralogía de la muestra, el porcentaje debe ser representado en
fracción (ejemplo: 25% es igual a 0.25).

In [175… muestra = {"cuarzo": 0.48, "plagioclasas": 0.27, "feldespato": 0.11, "biotita": 0.08, "pirita": 0.06}

In [176… muestra

{'cuarzo': 0.48,
Out[176…
'plagioclasas': 0.27,
'feldespato': 0.11,
'biotita': 0.08,
'pirita': 0.06}

14.4. Mineralogía de una muestra de roca (Parte 2)


Usando el diccionario obtenido en el ejercicio 14.3, crear un bucle definido que muestre el nombre y el porcentaje de cada mineral.\ Usar
el siguiente formato: Abundancia de ____ en la muestra: _____ %

Nota: usar la función print para mostrar los resultados de cada mineral.

In [177… for mineral, porcentaje in [Link]():


print(f"Abundancia de {mineral} en la muestra: {porcentaje:.0%}")

Abundancia de cuarzo en la muestra: 48%


Abundancia de plagioclasas en la muestra: 27%
Abundancia de feldespato en la muestra: 11%
Abundancia de biotita en la muestra: 8%
Abundancia de pirita en la muestra: 6%

14.5. Normalización de porcentajes para clasificación petrográfica


Crear una función con nombre streckeisen con las siguientes características:

La función usará como parámetro de entrada a un diccionario.


La función tomará los porcentajes de cuarzo , feldespato y plagioclasas del diccionario y los normalizará.
La función debe devolver como resultado un diccionario conteniendo solamente los 3 minerales y sus respectivos porcentajes
normalizados.

Usar el diccionario del ejercicio 14.3 en la función y mostrar el resultado final.

In [178… def streckeisen(diccionario):


cz = [Link]("cuarzo", 0)
plg = [Link]("plagioclasas", 0)
fp = [Link]("feldespato", 0)

suma = cz + plg + fp

cz /= suma
plg /= suma
fp /= suma

resultado = dict([("cuarzo", cz), ("plagioclasas", plg), ("feldespato", fp)])


return resultado

In [179… streckeisen(muestra)

{'cuarzo': 0.5581395348837209,
Out[179…
'plagioclasas': 0.313953488372093,
'feldespato': 0.12790697674418605}

14.6. Prueba de algoritmo


Usar la función streckeisen creada en el ejercicio 14.5 para normalizar una muestra con la siguiente mineralogía:\ Cuarzo (41%),
plagioclasas (25%), anfíboles (17%), biotita (12%), pirita (5%).

Nota: en caso la función no evalúe la muestra de forma correcta o indique error, se deberá modificar la función hasta que
pueda resolverla.

In [180… muestra2 = {"cuarzo": 0.41, "plagioclasas": 0.25, "anfíboles": 0.17, "biotita": 0.12, "pirita": 0.05}

In [181… streckeisen(muestra2)

{'cuarzo': 0.6212121212121212,
Out[181…
'plagioclasas': 0.37878787878787884,
'feldespato': 0.0}

14.7. Buzamiento aparente en un talud


Un estrato rocoso que aflora en el talud de una carretera tiene un azimut de 150° y un buzamiento aparente de 33°. Calcular el buzamiento
real del estrato teniendo en cuenta que el azimut del talud de carretera es de 180°. Usar la siguiente fórmula:

tan(ϕaparente )
ϕreal = arctan( )
cos(β)

Donde:

ϕreal : buzamiento real


ϕaparente : buzamiento aparente
β : ángulo entre el azimut del estrato y el azimut del talud

Nota: usar la librería math o numpy para realizar el cálculo trigonométrico.

Asignando los valores de buzamiento aparente a dip_aparente y el ángulo β a beta :

In [182… dip_aparente = 33
beta = abs(180 - 150)

Ahora, importaremos la librería math para poder usar las funciones tangente, seno y arcotangente.\ Primero usaremos la función
[Link]() para transformar los ángulos de grados sexagesimales a radianes.

In [183… import math

In [184… dip_aparente = [Link](dip_aparente)


beta = [Link](beta)

Ahora, usaremos [Link]() , [Link]() y [Link]() para calcular el buzamiento real en radianes:

In [185… dip_real = [Link](([Link](dip_aparente) / [Link](beta)))


dip_real

0.6434187340999458
Out[185…

El buzamiento está en radianes, debemos transformarlo a grados sexagesimales:

In [186… [Link](dip_real)

36.865177923577036
Out[186…

Respuesta: el buzamiento real del estrato rocoso es de aprox. 37°.

También podría gustarte