Tema 14. Archivos TXT y CSV
Explicación de la creación, apertura, cierre y edición de archivos en Python 3.
Archivos TXT
Leyendo el primer txt
txt
Vamos a crear un archivo txt
con el editor de textos que diga:
y lo guardaremos en la carpeta datasets con el nombre first_read.txt
.
A continuación, vamos a cargar el archivo que acabamos de crear en este mismo notebook. Para ello vamos a usar la función open()
y los métodos .read()
y .close()
, para abrir, leer y cerrar, respectivamente, el archivo txt
.
La función
open()
abre el archivo indicado y nos permite acceder a él. Como parámetro necesita el path del archivo que queremos abrir.El método
.read()
lo usamos para leer el contenido del output que nos proporciona la funciónopen()
al cual hemos llamadof
Cuando hayamos acabado de trabajar con el archivo
f
, hay que cerrarlo. Este proceso se lleva a cabo con el método.close()
Otra forma de abrir el archivo y guardarlo en la variable f
sería:
Observación. Con esta nueva sintaxis ya no es necesario hacer uso del método .close()
para cerrar el archivo f
. El comando with
garantiza que el objeto file
precedente, f
, se cerrará automáticamente después de salir del bloque de código.
Leyendo parcialmente un archivo
Dado un archivo txt
abierto con la función open()
, no es necesario leerlo al completo. Si solamente nos interesase leer una parte, podríamos indicárselo por parámetro al método .read()
En el siguiente chunk de código vamos a leer solamente los 7 primeros caracteres del archivo f
Leyendo un archivo línea a línea
El método .readline()
hace que el archivo f
sea leido línea a línea.
Si solamente llamamos una vez al método
.readline()
leeremos únicamente la primera línea del fichero.Si llamamos dos veces al método, leeremos las dos primeras líneas del fichero.
Y así sucesivamente.
En nuestro caso solo tenemos una línea, de modo que nos sirve una llamada al método .readline()
para leer todo el fichero. Sin embargo, podemos probar con un archivo con más de una línea como el first_read_multiline
que hemos creado para esta clase.
Escribiendo un archivo txt
txt
Podemos crear y escribir un archivo txt
desde este mismo notebook.
Para ello, volveremos a usar la función open()
, pero esta vez con un parámetro adicional: mode = "w"
. Este nuevo parámetro nos permitirá acceder al archivo en modo escritura, mientras que si no indicásemos nada, por defecto accederíamos en modo lectura.
Para escribir en el fichero, tendremos que usar el método .write()
e indicarle el string que queremos plasmar en nuestro txt
.
Además, para crear un nuevo archivo txt
, a la hora de introducir el path (que será el mismo que el del archivo first_read.txt
), como nombre del archivo indicaremos first_write.txt
.
¡Cuidado! El archivo que creemos no debe existir. En caso de existir un archivo con el mismo nombre, lo estaríamos rescribiendo.
Comprobamos que se ha guardado el nuevo archivo txt
llamado first_write
en nuestra carpeta datasets.
Una vez comprobada la existencia de este archivo txt
, podemos leerlo desde este notebook tal cuál hemos hecho en el apartado anterior
Al haber más de una línea, también podemos leer todas ellas con un bucle:
Creando un txt
vacío
txt
vacíoSi queremos crear un txt
vacío, indicamos mode = "x"
.
En este caso vamos a crear un txt
vacío llamado first_empty
¡Cuidado! El archivo que creemos no debe existir. En caso de existir un archivo con el mismo nombre, nos saltaría error indicando que el archivo en cuestión ya existe.
Sobrescribiendo un archivo txt
existente
txt
existenteAl igual que podemos crear y escribir un archivo txt
desde 0, podemos modificar un archivo txt
ya existente.
En este caso, el parámetro mode
debe ser igualado a "a"
.
Vamos entonces a modificar el archivo first_write
y vamos a añadirle al final la siguiente frase:
"\nY esta última línea se ha añadido posteriormente."
Observación. Añadimos el comando al principio de la frase para que ésta se considere una nueva frase tras un salto de línea.
¡Cuidado! Cada vez que ejecutéis la celda anterior se añadirá el string indicado. Por tanto, no la ejecutéis más de una vez u os encontraréis con la frase en cuestión repetida múltiples veces!
¡Cuidado! Si en vez de indicar mode = "a"
indicáis mode = "w"
eliminaréis el contenido del fichero y lo sobrescribiréis por completo por el string que indiquéis al método .write()
Eliminando archivos
En este caso vamos a tener que importar el módulo os
Para eliminar un archivo usaremos el método .remove()
al que por parámetro indicaremos el path de dicho archivo.
Podemos comprobar en la carpeta datasets que efectivamente ha dejado de existir el archivo first_empty
.
Para evitar errores, antes de proceder a la eliminación de un archivo, podemos comprobar su existencia con el método .path.exists()
, al que por parámetro le indicamos el path del archivo en cuestión.
Para realizar este ejemplo, vamos a volver a crear el txt
first_empty
. Luego comprobaremos su existencia y, de existir, lo eliminaremos. De no existir, lo indicaremos por pantalla.
Si volvemos a ejecutar la celda anterior, puesto que el archivo first_empty
se habrá eliminado, obtendremos el mensaje "El archivo que se quiere eliminar no existe"
Eliminando carpetas
Si se deseara eliminar toda una carpeta, esto sería posible con el método .rmdir()
.
Para ver su funcionamiento, vamos a crear una carpeta dentro de la carpeta datasets. A esta nueva carpeta la llamaremos carpeta_temporal
y estará vacía.
Observación. Este métodosolo nos permite eliminar carpetas vacías.
Navegamos hasta la carpeta datasets de nuestro Google Drive y comprobamos que efectivamente, la carpeta vacía que acabábamos de crear, carpeta_temporal
, ha sido eliminada.
Archivos CSV
Leyendo csv
con open()
csv
con open()
Además de usar la función open()
, vamos a necesitar algunos métodos del módulo csv
.
Empezaremos mostrando como leer un csv
haciendo uso del método .reader()
del módulo csv
.
En este caso vamos a trabajar con el archivo csv_example.csv
. Si abrimos el archivo, veremos que todos los valores están separados por comas y cada observación se encuentra en una línea diferente.
Para leerlo, ejecutaremos el siguiente chunk de código:
Con la función open()
hemos accedido al archivo, al cuál hemos identificado por f
. A continuación, hemos usado el método .reader()
para leer el archivo f
. Dicho método nos ha devuelto el iterable reader
, del cuál hemos mostrado todas sus filas iterando con un bucle for
.
Cambiando el separador
Por defecto, los archivos csv
tienen como delimitador la coma ,
. No obstante, algunos archivos csv
usan otros delimitadores. Las alternativas más populares a la coma suelen ser |
o .
Observemos el archivo csv_delimiter_example.csv
, donde esta vez sus elementos están separados por tabuladores, .
El método .reader()
nos permite configurar dicho separador con el parámetro delimiter
.
Eliminando espacios adicionales
A veces puede ocurrir que algunos csv
tengan un espacio en blanco tras el delimitador, cosa que se ve reflejado al leer los datos.
Para eliminar estos espacios en blanco adicionales, el método .reader()
trae el parámetro skipinitialspace
. Si lo igualamos a True
, los espacios adicionales desaparecerán.
Observemos que el archivo csv_spaces_example.csv
tiene espacios en blanco adicionales tras el separador, que es la coma. Veamos la diferencia entre igualar el parámetro skipinitialspace
a True
o a False
.
Observación. Salvo la primera entrada de cada fila, todas tienen un espacio inicial adicional.
Comillas en las entradas
Algunos archivos csv
puede que tengan entradas entre comillas. Si no indicamos nada, por defecto aparecerán las comillas en las entradas tras haber leído el fichero.
Si en cambio queremos deshacernos de ellas, disponemos del parámetro quoting
, que admite diferentes valores:
csv.QUOTE_ALL
: indica al objetoreader
que todos los valores en el archivocsv
están entre comillascsv.QUOTE_MINIMAL
: indica al objetoreader
que los valores en el archivocsv
que están entre comillas son entradas que contienen caracteres como el delimitador, comillas o cualquier caracter de terminación de líneacsv.QUOTE_NONNUMERIC
: indica al objetoreader
que los valores en el archivocsv
que están entre comillas son entradas que contienen entradas no-numéricascsv.QUOTE_NONE
: indica al objetoreader
que ninguno los valores en el archivocsv
están entre comillas
Observemos el archivo csv_quotation_example.csv
, donde las observaciones entre comillas son aquellas que no tienen valores numéricos. En este caso, nos convendría usar la opción csv.QUOTE_NONNUMERIC
Observación. Las entradas numéricas han dejado de ser leídas como strings y han pasado a ser consideradas entradas de tipo float
.
Si en cambio hubiésemos usado la opción csv.QUOTATE_ALL
, no hubiésemos obtenido ningún error, pero las entradas numéricas habrían sido tratadas como string
.
Dialectos
Hasta ahora solamente hemos usado uno de los parámetros cada vez, pero podría darse el caso de que tuviésemos un csv con un delimitador distinto a la coma, con espacios adicionales y entradas entrecomilladas a causa de contener delimitadores o finales de línea.
Una opción sería indicar todos los parámetros a la función, pero existe una alternativa que nos será muy útil en caso de no estar tratando con un solo archivo csv
sino con múltiples con formatos similares. Es el caso de los dialectos.
Los dialectos ayudan a agrupar patrones de formato específicos como el delimitador, las comillas, los espacios adicionales tras los delimitadores...
En caso de querer usar nuestro dialecto personalizado, .reader()
nos ofrece el parámetros dialect
al cual podemos pasarle dicho dialecto.
Consideremos el archivo csv_dialect_example.csv
, el cual tiene el delimitador |
, espacios adicionales y todos sus valores no numéricos entrecomillados.
En vez de indicar todos esos parámetros al método .reader()
, vamos a crear nuestro dialecto, my_dialect
, con el método .register_dialect()
y se lo vamos a pasar al parámetro dialect
de .reader()
Al método .register_dialect()
en primer lugar le hemos dado un nombre en formato string
y luego hemos configurado los parámetros delimiter
, skipinitialspace
y quoting
.
A continuación, al método .reader()
le hemos pasado el nombre del dialecto, my_dialect
, al parámetro dialect
y se ha leído el archivo correctamente.
Una vez creado el dialecto personalizado, podemos usarlo tantas veces como queramos para abrir y leer archivos csv
con el mismo formato, en este caso, que csv_dialect_example.csv
.
Diccionarios y csv
csv
En este caso vamos a trabajar de nuevo con el archivo csv_example.csv
.
Para leerlo, usaremos el método .DictReader()
del módulo csv
, lo que nos devolverá un objeto OrderedDict
, que es iterable.
Observación. Podríamos usar la función dict()
dentro del print()
para mostrar los objetos OrderedDict
como diccionarios.
Observación. Si se usa una versión de Python
3.8 o superior, podría ser que no fuera necesario usar la función dict()
pues el resultado de .DictReader()
ya sería un diccionario.
Escribiendo csv
csv
Para crear y escribir un csv
usamos la función open()
junto al método csv.writer()
:
Si ahora vamos a la carpeta datasets, observaremos que ha aparecido un nuevo archivo llamado csv_write.csv
el cual contiene como valores las entradas de la lista data
, donde cada sublista corresponde a una fila del csv
gracias al bucle for
y al método .writerow()
.
Podríamos haber obtenido exactamente el mismo resultado sin haber usado un bucle, lo que para ello tendríamos que haber hecho uso del método .writerows()
.
Si ahora vamos a la carpeta datasets, observaremos que ha aparecido un nuevo archivo llamado csv_write_writerows.csv
el cual contiene como valores las entradas de la lista data
, donde cada sublista corresponde a una fila del csv
gracias al método .writerows()
.
Diccionarios y csv
También podemos escribir un csv
a partir de un diccionario. Para ello tendremos que usar el método .DictWriter()
.
En este caso, los datos están guardado en una lista de diccionarios llamada data
. A continuación guardamos la cabecera en la variable header
como una lista de los nombres de las variables.
Abrimos (y creamos) el archivo csv_write_dict.csv
y creamos el objeto writer
con el método .DictWriter()
al cual le pasamos la cabecera header
mediante el parámetro fieldnames
.
Finalmente, escribimos en primer lugar la cabecera con el método .writeheader()
y luego, con la ayuda de un bucle for
, cada observación, correspondiente a cada uno de los diccionarios de la lista data
, en una fila diferente con el método .writerow()
.
Podríamos haber obtenido el mismo resultado sin usar ningún bucle, pero haciendo uso del método .writerows()
Observamos que efectivamente tanto el archivo csv_write_dict.csv
como csv_write_dict_writerows.csv
son idénticos.
REPASO
Ejercicio 1
Pídele al usuario el nombre, el apellido, la edad y su color favorito. Guarda la información en un diccionario de claves name, surname, age y color. Crea y escribe un txt con 4 frases, una en cada línea. La primera debe indicar el nombre del usuario; la segunda, el apellido; la tercera, la edad; y la última, el color favorito del usuario.
Ejercicio 2
Lee el archivo txt creado en el ejercicio anterior para ver que se ha creado correctamente.
Ejercicio 3
Crea un archivo txt vacío y llámalo ej3.txt.
Ejercicio 4
Elimina el archivo creado en el ejercicio 3.
Ejercicio 5
Crea un archivo txt vacío y llámalo ej5.txt. Sobreescribelo con las siguientes líneas: "x,y,Color,Shape \n" "1,1,#6fb7ff,< \n" "-1,1,#ffa66f,v \n" "-1,-1,#ffee6f,> \n" "1,-1,#db6fff,^ \n"
Ejercicio 6
Lee el archivo txt del ejercicio 5 como si fuera un archivo csv. Guarda las filas del objeto reader en una lista llamada df. Al final tendrás una lista con 5 listas de tamaño 4.
Ejercicio 7
Utiliza el método .read_csv() de pandas para leer el contenido del txt del ejercicio 5 y guardarlo en un dataframe llamado df.
Last updated