Python
Tutorial Python: Módulo csv
Domina el módulo csv de Python para leer, escribir y gestionar archivos CSV con dialectos personalizados y manejo avanzado de datos.
Aprende Python y certifícateLectura de archivos CSV
El formato CSV (Comma-Separated Values) es uno de los formatos más comunes para almacenar datos tabulares. Python incluye el módulo csv en su biblioteca estándar, que proporciona herramientas eficientes para leer, procesar y analizar archivos CSV sin necesidad de instalar bibliotecas externas.
Fundamentos de la lectura de archivos CSV
Para leer un archivo CSV en Python, primero necesitamos importar el módulo csv y abrir el archivo utilizando la función open()
:
import csv
with open('datos.csv', 'r', newline='', encoding='utf-8') as archivo:
# Operaciones de lectura
Observa los parámetros utilizados:
- El parámetro
'r'
indica que abrimos el archivo en modo lectura newline=''
evita problemas con diferentes interpretaciones de saltos de línea en distintos sistemas operativosencoding='utf-8'
especifica la codificación del archivo para manejar correctamente caracteres especiales
Utilizando el lector CSV básico
El módulo csv proporciona la clase reader
que nos permite iterar sobre las filas del archivo CSV:
import csv
with open('contactos.csv', 'r', newline='', encoding='utf-8') as archivo:
lector_csv = csv.reader(archivo)
# Leer la primera fila como encabezados
encabezados = next(lector_csv)
print(f"Columnas: {encabezados}")
# Leer el resto de filas
for fila in lector_csv:
print(fila)
Cada fila se devuelve como una lista de cadenas. Si nuestro archivo contactos.csv
contiene:
nombre,email,telefono
Ana García,ana@ejemplo.com,612345678
Carlos López,carlos@ejemplo.com,698765432
El código anterior mostraría:
Columnas: ['nombre', 'email', 'telefono']
['Ana García', 'ana@ejemplo.com', '612345678']
['Carlos López', 'carlos@ejemplo.com', '698765432']
Utilizando DictReader para acceso por nombre de columna
Una forma más conveniente de trabajar con archivos CSV es utilizando csv.DictReader
, que devuelve cada fila como un diccionario donde las claves son los nombres de las columnas:
import csv
with open('productos.csv', 'r', newline='', encoding='utf-8') as archivo:
lector_dict = csv.DictReader(archivo)
# Imprimir los nombres de las columnas
print(f"Columnas: {lector_dict.fieldnames}")
# Procesar cada fila como un diccionario
for fila in lector_dict:
print(f"Producto: {fila['nombre']}, Precio: {fila['precio']}€, Stock: {fila['stock']}")
Si nuestro archivo productos.csv
contiene:
nombre,precio,stock
Teclado mecánico,89.99,15
Monitor 24",159.95,8
Ratón inalámbrico,29.99,22
El código mostraría:
Columnas: ['nombre', 'precio', 'stock']
Producto: Teclado mecánico, Precio: 89.99€, Stock: 15
Producto: Monitor 24", Precio: 159.95€, Stock: 8
Producto: Ratón inalámbrico, Precio: 29.99€, Stock: 22
La ventaja de DictReader
es que podemos acceder a los valores por el nombre de la columna, lo que hace el código más legible y menos propenso a errores si cambia el orden de las columnas.
Manejo de delimitadores personalizados
No todos los archivos CSV utilizan comas como separadores. Algunos utilizan punto y coma (;), tabulaciones (\t) u otros caracteres. Podemos especificar el delimitador al crear el lector:
import csv
# Para archivos que usan punto y coma como separador (común en países europeos)
with open('datos_europeos.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.reader(archivo, delimiter=';')
for fila in lector:
print(fila)
# Para archivos TSV (valores separados por tabulaciones)
with open('datos.tsv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.reader(archivo, delimiter='\t')
for fila in lector:
print(fila)
Conversión de tipos de datos
El módulo csv siempre devuelve los datos como cadenas de texto, incluso para valores numéricos. A menudo necesitaremos convertir estos valores a tipos de datos apropiados:
import csv
with open('ventas.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.DictReader(archivo)
total_ventas = 0
for fila in lector:
# Convertir el precio de string a float
precio = float(fila['precio'])
# Convertir la cantidad de string a int
cantidad = int(fila['cantidad'])
subtotal = precio * cantidad
total_ventas += subtotal
print(f"Producto: {fila['producto']}, Subtotal: {subtotal:.2f}€")
print(f"Total de ventas: {total_ventas:.2f}€")
Manejo de errores comunes
Al trabajar con archivos CSV, es importante manejar posibles errores:
import csv
import os
nombre_archivo = 'datos.csv'
try:
# Verificar si el archivo existe
if not os.path.exists(nombre_archivo):
raise FileNotFoundError(f"El archivo {nombre_archivo} no existe")
with open(nombre_archivo, 'r', newline='', encoding='utf-8') as archivo:
try:
lector = csv.reader(archivo)
for fila in lector:
# Verificar si la fila tiene el número esperado de columnas
if len(fila) < 3:
print(f"Advertencia: La fila {lector.line_num} no tiene suficientes columnas")
continue
print(fila)
except csv.Error as e:
print(f"Error al procesar el CSV en la línea {lector.line_num}: {e}")
except Exception as e:
print(f"Error: {e}")
Filtrado y procesamiento de datos
Una tarea común es filtrar y procesar datos de un archivo CSV:
import csv
with open('empleados.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.DictReader(archivo)
# Filtrar empleados del departamento de Tecnología con salario > 50000
empleados_filtrados = [
empleado for empleado in lector
if empleado['departamento'] == 'Tecnología' and float(empleado['salario']) > 50000
]
# Ordenar por salario (de mayor a menor)
empleados_ordenados = sorted(
empleados_filtrados,
key=lambda emp: float(emp['salario']),
reverse=True
)
# Mostrar resultados
print(f"Empleados de Tecnología con salario > 50000€ (ordenados por salario):")
for empleado in empleados_ordenados:
print(f"{empleado['nombre']}: {empleado['salario']}€")
Análisis básico de datos CSV
Podemos realizar análisis básicos de datos directamente con el módulo csv:
import csv
from collections import Counter
with open('ventas_regionales.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.DictReader(archivo)
# Extraer datos para análisis
ventas_por_region = {}
productos_vendidos = Counter()
for fila in lector:
region = fila['region']
producto = fila['producto']
cantidad = int(fila['cantidad'])
# Acumular ventas por región
if region not in ventas_por_region:
ventas_por_region[region] = 0
ventas_por_region[region] += cantidad
# Contar productos vendidos
productos_vendidos[producto] += cantidad
# Mostrar resultados
print("Ventas por región:")
for region, total in sorted(ventas_por_region.items(), key=lambda x: x[1], reverse=True):
print(f"{region}: {total} unidades")
print("\nProductos más vendidos:")
for producto, cantidad in productos_vendidos.most_common(3):
print(f"{producto}: {cantidad} unidades")
Conversión entre CSV y estructuras de datos Python
Podemos convertir fácilmente datos CSV a estructuras de datos Python y viceversa:
import csv
# Convertir CSV a lista de diccionarios
def csv_a_lista_dict(nombre_archivo):
with open(nombre_archivo, 'r', newline='', encoding='utf-8') as archivo:
return list(csv.DictReader(archivo))
# Convertir CSV a lista de listas
def csv_a_lista_listas(nombre_archivo):
with open(nombre_archivo, 'r', newline='', encoding='utf-8') as archivo:
lector = csv.reader(archivo)
return list(lector)
# Ejemplo de uso
datos_dict = csv_a_lista_dict('datos.csv')
print(f"Primer registro como diccionario: {datos_dict[0]}")
datos_lista = csv_a_lista_listas('datos.csv')
print(f"Encabezados: {datos_lista[0]}")
print(f"Primera fila de datos: {datos_lista[1]}")
Esta función nos permite cargar todo el contenido de un archivo CSV en memoria para procesarlo con las potentes herramientas de manipulación de datos de Python, como comprensiones de listas, funciones map()
, filter()
, etc.
Escritura de archivos CSV
Así como Python facilita la lectura de archivos CSV, también proporciona herramientas eficientes para crear y escribir datos en este formato. La escritura de archivos CSV es fundamental cuando necesitamos exportar resultados de análisis, generar informes o compartir datos con otros sistemas.
Fundamentos de la escritura de archivos CSV
Para escribir en un archivo CSV, utilizamos el módulo csv con la función open()
en modo escritura:
import csv
with open('nuevo_archivo.csv', 'w', newline='', encoding='utf-8') as archivo:
# Operaciones de escritura
Los parámetros clave son:
'w'
indica modo escritura (sobrescribe el archivo si existe)newline=''
evita la inserción de líneas en blanco adicionalesencoding='utf-8'
garantiza la correcta codificación de caracteres especiales
Escritura básica con csv.writer
La clase writer
permite escribir datos en formato CSV de manera sencilla:
import csv
# Datos a escribir
datos = [
['Nombre', 'Edad', 'Ciudad'], # Encabezados
['Elena Martínez', 28, 'Madrid'],
['Pablo Sánchez', 34, 'Barcelona'],
['Laura Gómez', 31, 'Valencia']
]
with open('personas.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(archivo)
# Escribir todas las filas de una vez
escritor.writerows(datos)
# Alternativamente, podemos escribir fila por fila:
# for fila in datos:
# escritor.writerow(fila)
El archivo resultante personas.csv
contendrá:
Nombre,Edad,Ciudad
Elena Martínez,28,Madrid
Pablo Sánchez,34,Barcelona
Laura Gómez,31,Valencia
Escritura con csv.DictWriter
Para una escritura más intuitiva, especialmente cuando trabajamos con diccionarios, podemos usar csv.DictWriter
:
import csv
# Datos como lista de diccionarios
productos = [
{'id': 1001, 'nombre': 'Portátil ultraligero', 'precio': 899.99, 'stock': 12},
{'id': 1002, 'nombre': 'Tablet 10"', 'precio': 349.50, 'stock': 25},
{'id': 1003, 'nombre': 'Smartphone premium', 'precio': 749.00, 'stock': 8}
]
# Definir los campos (columnas) que queremos incluir
campos = ['id', 'nombre', 'precio', 'stock']
with open('inventario.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.DictWriter(archivo, fieldnames=campos)
# Escribir la fila de encabezados
escritor.writeheader()
# Escribir los datos
escritor.writerows(productos)
El archivo inventario.csv
resultante contendrá:
id,nombre,precio,stock
1001,Portátil ultraligero,899.99,12
1002,"Tablet 10""",349.5,25
1003,Smartphone premium,749.0,8
Observa cómo el módulo csv maneja automáticamente el escapado de comillas en el texto "Tablet 10"".
Añadir datos a un archivo existente
Para añadir datos a un archivo CSV existente sin sobrescribirlo, usamos el modo 'a'
(append):
import csv
import os
nuevo_producto = ['1004', 'Auriculares inalámbricos', '89.95', '30']
with open('inventario.csv', 'a', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(archivo)
escritor.writerow(nuevo_producto)
Si necesitamos verificar si el archivo ya existe para decidir si escribir los encabezados:
import csv
import os
archivo_existe = os.path.isfile('ventas_mensuales.csv')
with open('ventas_mensuales.csv', 'a', newline='', encoding='utf-8') as archivo:
campos = ['fecha', 'producto', 'cantidad', 'precio_unitario', 'total']
escritor = csv.DictWriter(archivo, fieldnames=campos)
# Escribir encabezados solo si el archivo es nuevo
if not archivo_existe:
escritor.writeheader()
# Añadir nueva venta
nueva_venta = {
'fecha': '2023-11-15',
'producto': 'Monitor curvo 32"',
'cantidad': 2,
'precio_unitario': 299.99,
'total': 599.98
}
escritor.writerow(nueva_venta)
Personalización del formato de salida
Podemos personalizar varios aspectos del formato CSV de salida:
import csv
datos = [
['Producto', 'Descripción', 'Precio'],
['Cafetera', 'Cafetera automática con molinillo integrado', 249.99],
['Batidora', 'Batidora de vaso de alta potencia', 89.95],
['Tostadora', 'Tostadora de 2 ranuras con control de temperatura', 45.50]
]
with open('catalogo.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(
archivo,
delimiter=';', # Usar punto y coma como separador
quotechar='"', # Carácter para entrecomillar texto
quoting=csv.QUOTE_MINIMAL # Entrecomillar solo cuando sea necesario
)
escritor.writerows(datos)
El archivo catalogo.csv
resultante usará punto y coma como separador:
Producto;Descripción;Precio
Cafetera;"Cafetera automática con molinillo integrado";249.99
Batidora;"Batidora de vaso de alta potencia";89.95
Tostadora;"Tostadora de 2 ranuras con control de temperatura";45.5
Las opciones de quoting
disponibles son:
csv.QUOTE_MINIMAL
: Entrecomilla solo campos que contienen el delimitador o el quotecharcsv.QUOTE_ALL
: Entrecomilla todos los camposcsv.QUOTE_NONNUMERIC
: Entrecomilla campos no numéricoscsv.QUOTE_NONE
: No entrecomilla ningún campo
Transformación de datos antes de escribir
A menudo necesitamos transformar o formatear datos antes de escribirlos en un CSV:
import csv
from datetime import datetime
# Datos de transacciones
transacciones = [
{'id': 'T001', 'fecha': datetime(2023, 11, 10), 'importe': 125.50, 'completada': True},
{'id': 'T002', 'fecha': datetime(2023, 11, 11), 'importe': 89.99, 'completada': False},
{'id': 'T003', 'fecha': datetime(2023, 11, 12), 'importe': 250.00, 'completada': True}
]
with open('transacciones.csv', 'w', newline='', encoding='utf-8') as archivo:
campos = ['id', 'fecha', 'importe', 'estado']
escritor = csv.DictWriter(archivo, fieldnames=campos)
escritor.writeheader()
for t in transacciones:
# Transformar datos antes de escribir
fila = {
'id': t['id'],
'fecha': t['fecha'].strftime('%d/%m/%Y'), # Formatear fecha
'importe': f"{t['importe']:.2f}", # Formatear número
'estado': 'Completada' if t['completada'] else 'Pendiente' # Texto descriptivo
}
escritor.writerow(fila)
El archivo resultante tendrá los datos formateados:
id,fecha,importe,estado
T001,10/11/2023,125.50,Completada
T002,11/11/2023,89.99,Pendiente
T003,12/11/2023,250.00,Completada
Exportación de estructuras de datos a CSV
Podemos exportar fácilmente estructuras de datos Python a archivos CSV:
import csv
# Convertir una lista de diccionarios a CSV
def lista_dict_a_csv(datos, nombre_archivo, campos=None):
# Si no se especifican campos, usar las claves del primer diccionario
if campos is None and datos:
campos = datos[0].keys()
with open(nombre_archivo, 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.DictWriter(archivo, fieldnames=campos)
escritor.writeheader()
escritor.writerows(datos)
# Ejemplo: exportar resultados de análisis
resultados_analisis = [
{'muestra': 'A1', 'ph': 7.2, 'temperatura': 22.5, 'contaminantes': 'No'},
{'muestra': 'B2', 'ph': 6.8, 'temperatura': 23.1, 'contaminantes': 'Sí'},
{'muestra': 'C3', 'ph': 7.5, 'temperatura': 21.8, 'contaminantes': 'No'}
]
# Exportar solo ciertos campos en un orden específico
lista_dict_a_csv(
resultados_analisis,
'resultados_laboratorio.csv',
campos=['muestra', 'ph', 'temperatura', 'contaminantes']
)
Manejo de errores en la escritura
Es importante implementar un manejo adecuado de errores al escribir archivos CSV:
import csv
import os
def exportar_datos_seguro(datos, ruta_archivo):
# Crear directorio si no existe
directorio = os.path.dirname(ruta_archivo)
if directorio and not os.path.exists(directorio):
try:
os.makedirs(directorio)
except OSError as e:
return f"Error al crear directorio: {e}"
try:
with open(ruta_archivo, 'w', newline='', encoding='utf-8') as archivo:
if not datos:
return "No hay datos para exportar"
# Determinar campos desde el primer elemento
campos = datos[0].keys()
escritor = csv.DictWriter(archivo, fieldnames=campos)
escritor.writeheader()
escritor.writerows(datos)
return f"Archivo guardado correctamente en {ruta_archivo}"
except PermissionError:
return "Error: No tienes permisos para escribir en esta ubicación"
except IOError as e:
return f"Error de E/S: {e}"
except Exception as e:
return f"Error inesperado: {e}"
# Ejemplo de uso
resultado = exportar_datos_seguro(
[{'nombre': 'Ana', 'edad': 28}, {'nombre': 'Luis', 'edad': 35}],
'datos/personal/empleados.csv'
)
print(resultado)
Caso práctico: Exportación de resultados de análisis
Veamos un ejemplo completo de exportación de resultados de análisis a CSV:
import csv
from datetime import datetime
def analizar_ventas(datos_ventas):
"""Analiza datos de ventas y devuelve estadísticas"""
if not datos_ventas:
return []
# Agrupar ventas por producto
ventas_por_producto = {}
for venta in datos_ventas:
producto = venta['producto']
cantidad = int(venta['cantidad'])
importe = float(venta['importe'])
if producto not in ventas_por_producto:
ventas_por_producto[producto] = {'unidades': 0, 'total': 0.0}
ventas_por_producto[producto]['unidades'] += cantidad
ventas_por_producto[producto]['total'] += importe
# Convertir a lista de resultados
resultados = []
for producto, datos in ventas_por_producto.items():
precio_medio = datos['total'] / datos['unidades'] if datos['unidades'] > 0 else 0
resultados.append({
'producto': producto,
'unidades_vendidas': datos['unidades'],
'importe_total': datos['total'],
'precio_medio': precio_medio
})
# Ordenar por importe total (de mayor a menor)
return sorted(resultados, key=lambda x: x['importe_total'], reverse=True)
# Datos de ejemplo
ventas = [
{'fecha': '2023-11-01', 'producto': 'Laptop', 'cantidad': '2', 'importe': '1799.98'},
{'fecha': '2023-11-02', 'producto': 'Monitor', 'cantidad': '3', 'importe': '599.97'},
{'fecha': '2023-11-02', 'producto': 'Laptop', 'cantidad': '1', 'importe': '899.99'},
{'fecha': '2023-11-03', 'producto': 'Teclado', 'cantidad': '5', 'importe': '249.95'},
{'fecha': '2023-11-04', 'producto': 'Monitor', 'cantidad': '2', 'importe': '399.98'}
]
# Analizar datos
resultados_analisis = analizar_ventas(ventas)
# Exportar resultados a CSV
nombre_archivo = f"informe_ventas_{datetime.now().strftime('%Y%m%d')}.csv"
with open(nombre_archivo, 'w', newline='', encoding='utf-8') as archivo:
campos = ['producto', 'unidades_vendidas', 'importe_total', 'precio_medio']
escritor = csv.DictWriter(archivo, fieldnames=campos)
escritor.writeheader()
for resultado in resultados_analisis:
# Formatear valores numéricos antes de escribir
fila = {
'producto': resultado['producto'],
'unidades_vendidas': resultado['unidades_vendidas'],
'importe_total': f"{resultado['importe_total']:.2f}",
'precio_medio': f"{resultado['precio_medio']:.2f}"
}
escritor.writerow(fila)
print(f"Informe generado: {nombre_archivo}")
Este ejemplo muestra cómo analizar datos de ventas y exportar los resultados a un archivo CSV con un nombre que incluye la fecha actual, facilitando la organización de informes periódicos.
Dialectos y formatos
Cuando trabajamos con archivos CSV, nos encontramos con que no existe un estándar único y universal para este formato. Diferentes aplicaciones, sistemas y regiones utilizan variaciones en la forma de estructurar los datos CSV. El módulo csv de Python aborda esta realidad mediante el concepto de "dialectos", que permite adaptar la lectura y escritura a diferentes formatos CSV.
Entendiendo los dialectos CSV
Un dialecto en el contexto del módulo csv define un conjunto de parámetros que determinan cómo se interpretan o generan los archivos CSV. Estos parámetros incluyen el delimitador, el carácter de comillas, y otras características de formato.
Python incluye varios dialectos predefinidos:
import csv
# Mostrar los dialectos disponibles
print(csv.list_dialects()) # Típicamente muestra: ['excel', 'excel-tab', 'unix']
Los dialectos predefinidos más comunes son:
- excel: El formato utilizado por Microsoft Excel (delimitador coma, comillas dobles)
- excel-tab: Similar a excel pero usando tabulaciones como delimitador
- unix: Un formato más estricto común en sistemas Unix (sin espacios después del delimitador)
Podemos especificar el dialecto al crear lectores o escritores CSV:
import csv
# Leer un archivo usando el dialecto excel
with open('datos.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.reader(archivo, dialect='excel')
for fila in lector:
print(fila)
# Escribir usando el dialecto unix
with open('datos_unix.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(archivo, dialect='unix')
escritor.writerow(['Nombre', 'Edad', 'Ciudad'])
escritor.writerow(['María', '29', 'Sevilla'])
Propiedades de los dialectos
Cada dialecto define varias propiedades que controlan el formato CSV:
import csv
# Examinar las propiedades del dialecto excel
dialecto = csv.get_dialect('excel')
print(f"Delimitador: '{dialecto.delimiter}'")
print(f"Carácter de comillas: '{dialecto.quotechar}'")
print(f"Estilo de comillas: {dialecto.quoting}")
print(f"Escapador: '{dialecto.escapechar}'")
print(f"Salto de línea: '{dialecto.lineterminator}'")
Las propiedades principales incluyen:
- delimiter: El carácter usado para separar campos (típicamente ',' o ';')
- quotechar: El carácter usado para rodear campos que contienen caracteres especiales
- quoting: Determina cuándo se deben usar comillas (QUOTE_MINIMAL, QUOTE_ALL, etc.)
- escapechar: Carácter usado para escapar el delimitador o las comillas
- lineterminator: Secuencia que marca el final de una línea
- doublequote: Si es True, las comillas dentro de un campo se duplican
- skipinitialspace: Si es True, se ignoran espacios después del delimitador
Creando dialectos personalizados
Cuando trabajamos con formatos CSV no estándar, podemos crear nuestros propios dialectos:
import csv
# Registrar un nuevo dialecto para archivos europeos (con ; como delimitador)
csv.register_dialect(
'europeo',
delimiter=';',
quotechar='"',
doublequote=True,
skipinitialspace=True,
lineterminator='\r\n',
quoting=csv.QUOTE_MINIMAL
)
# Usar el dialecto personalizado
with open('ventas_europa.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(archivo, dialect='europeo')
escritor.writerow(['Producto', 'Precio', 'Cantidad'])
escritor.writerow(['Portátil', '899,99', '5']) # Nota: coma como separador decimal
Los dialectos personalizados son especialmente útiles cuando necesitamos procesar archivos de diferentes fuentes o generar archivos para sistemas específicos.
Detectando dialectos automáticamente
Python ofrece una función experimental para detectar automáticamente el dialecto de un archivo CSV:
import csv
# Muestra de datos CSV
muestra = '''\
"producto";"precio";"stock"
"Laptop HP";"799,99";"12"
"Monitor Samsung";"349,50";"8"
"Teclado mecánico";"89,95";"15"
'''
# Detectar el dialecto
dialecto = csv.Sniffer().sniff(muestra)
print(f"Delimitador detectado: '{dialecto.delimiter}'")
print(f"Comillas detectadas: '{dialecto.quotechar}'")
# Determinar si tiene encabezados
tiene_encabezados = csv.Sniffer().has_header(muestra)
print(f"¿Tiene encabezados? {tiene_encabezados}")
# Usar el dialecto detectado para leer los datos
import io
lector = csv.reader(io.StringIO(muestra), dialect=dialecto)
for fila in lector:
print(fila)
Esta funcionalidad es útil cuando recibimos archivos CSV de fuentes desconocidas o variables.
Dialectos para casos específicos
Veamos algunos ejemplos de dialectos para casos específicos:
import csv
# Dialecto para archivos con campos separados por pipes (|)
csv.register_dialect(
'pipes',
delimiter='|',
quotechar='"',
doublequote=True,
lineterminator='\n'
)
# Dialecto para CSV sin comillas (útil para datos simples)
csv.register_dialect(
'sin_comillas',
delimiter=',',
quoting=csv.QUOTE_NONE,
escapechar='\\'
)
# Dialecto que entrecomilla todos los campos
csv.register_dialect(
'todo_comillas',
delimiter=',',
quotechar='"',
quoting=csv.QUOTE_ALL
)
Trabajando con formatos regionales
Los formatos CSV varían según la región. Por ejemplo, en muchos países europeos:
- Se usa punto y coma (;) como delimitador de campo
- Se usa coma (,) como separador decimal
Esto requiere consideraciones especiales:
import csv
import locale
# Configurar locale para formato europeo (opcional)
# locale.setlocale(locale.LC_ALL, 'es_ES.UTF-8')
# Datos de ventas con formato europeo
datos_ventas = [
['Producto', 'Precio', 'Cantidad', 'Total'],
['Portátil', '899,99', '2', '1799,98'],
['Monitor', '249,50', '3', '748,50'],
['Teclado', '45,95', '5', '229,75']
]
# Guardar en formato europeo
with open('ventas_formato_europeo.csv', 'w', newline='', encoding='utf-8') as archivo:
escritor = csv.writer(archivo, delimiter=';')
escritor.writerows(datos_ventas)
# Leer y convertir a formato numérico Python
with open('ventas_formato_europeo.csv', 'r', newline='', encoding='utf-8') as archivo:
lector = csv.reader(archivo, delimiter=';')
encabezados = next(lector)
for fila in lector:
# Convertir valores con coma decimal a float
precio = float(fila[1].replace(',', '.'))
cantidad = int(fila[2])
total = float(fila[3].replace(',', '.'))
print(f"{fila[0]}: {precio} € x {cantidad} = {total} €")
Preservando dialectos entre sesiones
Si necesitamos mantener consistencia en el formato de nuestros archivos CSV a lo largo del tiempo, podemos guardar la configuración del dialecto:
import csv
import json
# Definir un dialecto personalizado
csv.register_dialect(
'mi_formato',
delimiter='|',
quotechar='"',
doublequote=True,
skipinitialspace=True,
lineterminator='\n',
quoting=csv.QUOTE_MINIMAL
)
# Guardar la configuración del dialecto
dialecto = csv.get_dialect('mi_formato')
config_dialecto = {
'delimiter': dialecto.delimiter,
'quotechar': dialecto.quotechar,
'doublequote': dialecto.doublequote,
'skipinitialspace': dialecto.skipinitialspace,
'lineterminator': dialecto.lineterminator,
'quoting': dialecto.quoting
}
# Guardar en un archivo de configuración
with open('config_csv.json', 'w', encoding='utf-8') as f:
json.dump(config_dialecto, f, indent=2)
# En otra sesión, cargar la configuración
with open('config_csv.json', 'r', encoding='utf-8') as f:
config = json.load(f)
# Recrear el dialecto
csv.register_dialect(
'mi_formato_restaurado',
delimiter=config['delimiter'],
quotechar=config['quotechar'],
doublequote=config['doublequote'],
skipinitialspace=config['skipinitialspace'],
lineterminator=config['lineterminator'],
quoting=config['quoting']
)
Caso práctico: Convertir entre formatos CSV
Un caso de uso común es convertir archivos CSV entre diferentes formatos:
import csv
def convertir_formato_csv(archivo_origen, archivo_destino, dialecto_origen, dialecto_destino):
"""
Convierte un archivo CSV de un formato a otro.
Args:
archivo_origen: Ruta al archivo CSV de origen
archivo_destino: Ruta donde guardar el archivo convertido
dialecto_origen: Dialecto del archivo de origen
dialecto_destino: Dialecto para el archivo de destino
"""
# Leer datos con el dialecto de origen
with open(archivo_origen, 'r', newline='', encoding='utf-8') as f_origen:
lector = csv.reader(f_origen, dialect=dialecto_origen)
datos = list(lector)
# Escribir datos con el dialecto de destino
with open(archivo_destino, 'w', newline='', encoding='utf-8') as f_destino:
escritor = csv.writer(f_destino, dialect=dialecto_destino)
escritor.writerows(datos)
return len(datos)
# Ejemplo: Convertir de formato europeo (;) a formato estándar (,)
csv.register_dialect('europeo', delimiter=';', quotechar='"')
filas_convertidas = convertir_formato_csv(
'datos_europeos.csv',
'datos_estandar.csv',
'europeo',
'excel'
)
print(f"Conversión completada: {filas_convertidas} filas procesadas")
Trabajando con Excel y otros programas
Aunque el dialecto 'excel' funciona bien para la mayoría de los casos, a veces necesitamos ajustes adicionales para una compatibilidad perfecta:
import csv
# Dialecto optimizado para Excel (incluye BOM para caracteres Unicode)
with open('para_excel.csv', 'w', newline='', encoding='utf-8-sig') as archivo:
escritor = csv.writer(
archivo,
dialect='excel',
delimiter=',',
quotechar='"',
quoting=csv.QUOTE_MINIMAL
)
escritor.writerow(['Nombre', 'Departamento', 'Salario (€)'])
escritor.writerow(['José Martínez', 'Desarrollo', 52000])
escritor.writerow(['Ana García', 'Marketing', 48000])
escritor.writerow(['Carlos Rodríguez', 'Finanzas', 55000])
El uso de encoding='utf-8-sig'
añade una marca de orden de bytes (BOM) que ayuda a Excel a reconocer correctamente los caracteres Unicode.
Resumen de opciones de formato
Para referencia rápida, aquí hay un resumen de las opciones de formato más comunes:
import csv
# Opciones de formato comunes y sus valores
formatos_comunes = {
'excel_estandar': {
'delimiter': ',',
'quotechar': '"',
'quoting': csv.QUOTE_MINIMAL
},
'excel_europeo': {
'delimiter': ';',
'quotechar': '"',
'quoting': csv.QUOTE_MINIMAL
},
'tsv': {
'delimiter': '\t',
'quotechar': '"',
'quoting': csv.QUOTE_MINIMAL
},
'unix_simple': {
'delimiter': ',',
'quotechar': '"',
'quoting': csv.QUOTE_MINIMAL,
'lineterminator': '\n'
},
'personalizado_seguro': {
'delimiter': '|',
'quotechar': '"',
'quoting': csv.QUOTE_ALL, # Entrecomilla todos los campos
'doublequote': True, # Duplica las comillas internas
'escapechar': None # No usa carácter de escape
}
}
# Registrar estos formatos como dialectos
for nombre, opciones in formatos_comunes.items():
csv.register_dialect(nombre, **opciones)
Este enfoque permite seleccionar fácilmente el formato adecuado según las necesidades específicas de cada proyecto.
Ejercicios de esta lección Módulo csv
Evalúa tus conocimientos de esta lección Módulo csv con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Módulo math
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
Todas las lecciones de Python
Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Python
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender cómo leer archivos CSV utilizando csv.reader y csv.DictReader.
- Aprender a escribir archivos CSV con csv.writer y csv.DictWriter.
- Manejar delimitadores personalizados y convertir tipos de datos al leer CSV.
- Conocer el concepto de dialectos para adaptar la lectura y escritura a diferentes formatos CSV.
- Implementar manejo de errores y realizar análisis básico y transformación de datos CSV.