Combinar archivos CSV y conservar los nombres de origen
Combina en orden archivos CSV con la misma estructura de columnas y añade una columna source_file. Usa conjuntos de datos pequeños para comprobar nombres de elementos con comas, columnas faltantes y salidas ya existentes.
Contenido revisado 2026.09.19Incluye archivos de ejemplo
Ver el índice
La traducción se ha realizado con IA. Comprueba el código, las unidades y los valores junto con el original. La revisión por hablantes nativos de cada idioma aún no se ha completado. English
Para quién esPrincipiantes de Python que quieren combinar en una sola tabla archivos CSV de distintas fechas o de diferentes personas.
Preparación
Instala Python 3.12 o posterior y comprueba la versión en una terminal con python --version.
Extrae el ZIP de ejemplo en una carpeta nueva. No ejecutes el ejemplo desde dentro del archivo ZIP.
Abre una terminal en la carpeta que contiene example.py. Si el comando python no está disponible en Windows, usa py. En macOS o Linux, usa python3 si tu entorno lo requiere.
No se necesitan paquetes externos ni cuentas. Los archivos incluidos son datos sintéticos creados para este tutorial.
01Combina dos archivos en cinco filas
Si los números parecen incorrectos después de combinar archivos, puede ser difícil rastrear de dónde proceden. Este ejemplo conserva las cuatro columnas originales y añade source_file al final. El objetivo es poder identificar directamente el nombre del archivo original desde cada fila del resultado. Primero, suma las 2 y 3 filas de datos de los archivos de entrada y anota el total esperado de 5.
Busca inputs/sales_01.csv e inputs/sales_02.csv en la carpeta extraída.
Abre ambos archivos en un editor de texto y comprueba que la primera línea sea date,item,quantity,unit_price.
Ejecuta el comando siguiente en una terminal situada en la carpeta que contiene example.py.
Abre outputs/merged.csv y comprueba que haya cinco filas de datos y una columna source_file.
bash
python example.py
Mantener separadas las carpetas de entrada y salida evita que un merged.csv anterior se convierta en un archivo de entrada en una ejecución posterior. El código también localiza inputs en relación con example.py. Si conservas la estructura de carpetas al extraer el ZIP, no necesitas cambiar las rutas.
02Haz coincidir la estructura de columnas antes de combinar
Columna de entrada
Valor de ejemplo
Cómo lo trata este ejemplo
date
2026-09-01
Se conserva como texto
item
노트
Se conserva, incluidas comas y comillas
quantity
2
Se conserva como texto sin calcular
unit_price
2500
Se conserva como texto sin calcular
Deben coincidir tanto los nombres de las columnas como su orden. Por ejemplo, el script se detiene si un archivo usa qty en lugar de quantity o coloca unit_price en otra posición. No intenta adivinar significados ni alinear columnas automáticamente, lo que permite detectar cuándo se han mezclado formatos de distintos departamentos.
Los datos sintéticos incluyen “메모지, 대형” (bloc de notas grande) y “표지 "파랑"” (cubierta "azul"), que contiene comillas dobles. Leer un CSV usando simplemente split con comas puede dividir estos valores en campos incorrectos. Deja que el módulo estándar csv gestione las reglas de comillas y vuelve a escribir las filas tal como se leyeron.
03Código completo utilizado en este ejemplo
collect_rows comprueba el encabezado y las filas de cada CSV y añade el nombre del archivo original. Solo después de que todas las comprobaciones se superen, main crea una salida nueva. Este orden evita que quede una combinación parcial de los primeros archivos cuando un archivo posterior tiene columnas incorrectas.
example.py
"""inputs의 같은 구조 CSV를 결합합니다. 각 행에 원본 파일명을 붙입니다."""
import csv
import sys
from pathlib import Path
BASE = Path(__file__).resolve().parent
INPUT = BASE / "inputs"
OUTPUT = BASE / "outputs"
FIELDS = ["date", "item", "quantity", "unit_price"]
def collect_rows():
if INPUT.is_symlink() or not INPUT.is_dir():
raise ValueError("inputs 폴더가 없거나 링크입니다.")
if getattr(INPUT, "is_junction", lambda: False)():
raise ValueError("연결 디렉터리는 처리하지 않습니다.")
# inputs 바로 아래의 .csv 파일만 읽습니다. 순서를 명시해 결과를 재현합니다.
paths = sorted(
(p for p in INPUT.iterdir() if p.suffix.lower() == ".csv"),
key=lambda p: p.name.casefold(),
)
if not paths:
raise ValueError("inputs에 CSV 파일이 없습니다.")
merged = []
counts = []
for path in paths:
if path.is_symlink() or not path.is_file():
raise ValueError(f"일반 CSV 파일이 아닙니다: {path.name}")
with path.open("r", encoding="utf-8-sig", newline="") as stream:
reader = csv.DictReader(stream, strict=True)
if reader.fieldnames != FIELDS:
raise ValueError(f"{path.name}: 열 이름과 순서는 {FIELDS}여야 합니다.")
count = 0
for row in reader:
# 열이 많으면 None 키, 적으면 None 값이 생깁니다.
if None in row or any(value is None or not value.strip() for value in row.values()):
raise ValueError(f"{path.name}, {reader.line_num}행: 열 수 또는 빈 값을 확인하세요.")
merged.append({**row, "source_file": path.name})
count += 1
counts.append((path.name, count))
return merged, counts
def main():
if OUTPUT.exists() or OUTPUT.is_symlink():
raise FileExistsError("outputs가 이미 있습니다. 기존 결과를 옮긴 뒤 실행하세요.")
rows, counts = collect_rows() # 모든 파일을 검증한 다음에 출력합니다.
OUTPUT.mkdir()
target = OUTPUT / "merged.csv"
with target.open("x", encoding="utf-8-sig", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=FIELDS + ["source_file"])
writer.writeheader()
writer.writerows(rows)
for name, count in counts:
print(f"{name}: {count}행")
print(f"완료: {len(counts)}개 파일 → {len(rows)}행")
print(target)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, ValueError, csv.Error) as error:
print(f"중지: {error}", file=sys.stderr)
raise SystemExit(2)
Las comprobaciones aprovechan que DictReader añade una clave None cuando hay demasiados campos de datos y un valor None cuando hay demasiado pocos. También se rechazan las cadenas vacías y los valores formados solo por espacios. Configurar newline como cadena vacía y especificar una codificación compatible con BOM de UTF-8 mantiene coherente el tratamiento de saltos de línea y texto coreano.
04Compara tanto el número de filas como los archivos de origen
Orden de fila del resultado
item
quantity
source_file
1
노트
2
sales_01.csv
2
펜
3
sales_01.csv
3
노트
1
sales_02.csv
4
메모지, 대형
4
sales_02.csv
5
표지 "파랑"
1
sales_02.csv
La terminal muestra “sales_01.csv: 2행” (dos filas), “sales_02.csv: 3행” (tres filas) y “완료: 2개 파일 → 5행” (completado: dos archivos → cinco filas), en ese orden. El encabezado de la primera línea no se cuenta como dato. Ver 노트 (cuaderno) dos veces no es un error. Se conservan ambas filas originales; no se han calculado totales ni eliminado duplicados.
05Haz cuatro comprobaciones antes de confiar en el resultado
Comprueba que la suma de las filas de entrada, 5, coincida con el número de filas de datos del resultado.
Comprueba que dos filas tengan source_file igual a sales_01.csv y tres tengan sales_02.csv.
Comprueba que el nombre de item que contiene una coma permanezca en una sola celda y que las comillas dobles no hayan desaparecido.
Vuelve a abrir los dos archivos originales y confirma que su contenido no ha cambiado. Comprueba también que volver a ejecutar el script se detenga porque outputs ya existe.
En trabajo real, comprobar el número de filas es distinto de comprobar los totales. Aunque los totales monetarios coincidan por casualidad, podría faltar una fila y existir otra duplicada. Como este paso no realiza cálculos, empieza comparando el número de filas por origen y el texto original.
06Practica añadiendo un tercer archivo
Antes de volver a ejecutar, cambia el nombre de la primera carpeta outputs para conservarla. Añade sales_03.csv dentro de inputs con el mismo encabezado y una fila de datos. El recuento esperado de datos es seis. Comprueba que la nueva fila tenga sales_03.csv en source_file para ver cómo añadir una entrada afecta a la columna de trazabilidad.
Solo se incluyen archivos con extensión .csv situados directamente dentro de inputs. El script no busca recursivamente en subcarpetas ni combina notas de texto o libros de Excel. Si no encuentra archivos CSV, lo interpreta como una selección incorrecta de entrada y se detiene. Un CSV válido que solo tenga encabezado cuenta como 0 filas y no impide combinar los demás archivos.
07Revisa los errores en lugar de aceptar resultados parciales
Motivo de la detención
Dónde comprobar
Cómo corregirlo
Los nombres o el orden de las columnas no coinciden
La primera línea del archivo indicado
Haz coincidir exactamente las cuatro columnas obligatorias.
Número de campos incorrecto o valor vacío
El nombre del archivo y el número de línea indicado
Comprueba campos faltantes, delimitadores adicionales y valores vacíos.
Error de comillas CSV
Una comilla doble sin cerrar
Usa una copia cuya estructura se haya reparado en un editor CSV.
Error de codificación
La codificación con la que se guardó el archivo de entrada
Crea una copia exportada en UTF-8.
outputs already exists
La carpeta de resultados anterior
Mueve los resultados y vuelve a ejecutar.
Los números de línea de los errores se refieren a las líneas físicas leídas del CSV. En archivos CSV complejos con saltos de línea dentro de valores entre comillas, pueden diferir de los números de filas de datos de una hoja de cálculo. Usa primero el nombre del archivo indicado en el mensaje para localizar el origen.
08Dónde termina la combinación y empieza la validación de datos
Este script comprueba la estructura de columnas, los valores vacíos y la sintaxis CSV. No determina si quantity es numérico, si date es una fecha válida o si los importes cumplen las reglas de trabajo. Si necesitas cálculos después de una combinación sencilla, añade la conversión numérica y las comprobaciones de rangos permitidos como pasos de validación separados.
Todas las filas se recopilan en memoria y se guardan después de la validación, por lo que este ejemplo es adecuado para practicar con archivos de trabajo pequeños. Los CSV muy grandes requieren un diseño con salida temporal y procesamiento por etapas. Un error de disco durante el guardado puede dejar resultados parciales; no consideres la ejecución correcta si no aparece un mensaje de finalización. Los cambios simultáneos en los archivos de entrada y los fallos de rutas de red quedan fuera del alcance de esta verificación.
Registro de ejecución y verificación
2026-09-19 · Windows 11 · CPython 3.12.14 · Sin paquetes adicionales · Ejecutado en una copia temporal de la distribución
Se combinaron 2 archivos CSV en 5 filas y se comprobaron los recuentos de source_file
Se conservaron las celdas que contienen comas y comillas dobles
Se rechazaron encabezados incorrectos, campos faltantes o adicionales, valores vacíos y comillas mal formadas antes de crear la salida
Se comprobó el tratamiento de archivos CSV solo con encabezado y de la ausencia de archivos CSV
Se confirmó que los hashes SHA-256 de los originales no cambiaron y que se conservaba la salida existente
Límites de la verificación
No se midió el uso de memoria con archivos grandes.
No se valida el significado de negocio de los números y las fechas.
El código de ejemplo, los nombres de archivo y las claves de entrada se mantienen como en el original. Consulta también los comandos y los pasos de comprobación del texto traducido.
Material de práctica original · Guarda los archivos originales por separado antes de ejecutarlo.
Fuentes de referencia
Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.
Recorre las subcarpetas y registra en una tabla las rutas, extensiones, tamaños y fechas de modificación de los archivos. Empieza con 4 archivos de ejemplo pequeños, manteniendo intactos los originales y los resultados existentes.
Compara los nombres antiguos y nuevos en una tabla y comprueba conflictos. Solo un --apply explícito crea copias en una carpeta nueva, manteniendo los originales.