¿Qué es CSV?
CSV — Comma-Separated Values (Valores Separados por Comas) — es uno de los formatos de intercambio de datos más antiguos y universalmente comprendidos. A pesar de no tener un estándar oficial durante casi cuatro décadas, se convirtió en la lengua franca para la transferencia de datos tabulares entre hojas de cálculo, bases de datos y pipelines de datos. El RFC 4180 (2005) codificó la práctica común.
Un archivo CSV es texto plano donde cada línea representa un registro de datos, y los campos dentro de un registro están separados por un delimitador — tradicionalmente una coma, pero a veces un punto y coma (común en locales europeos donde la coma sirve como separador decimal), un tabulador (TSV), una barra vertical |, u otro delimitador acordado.
RFC 4180 — El Estándar de Facto
El RFC 4180 define estas reglas gramaticales:
- Cada registro está en su propia línea, terminada por CRLF (
\r\n). - El último registro puede o no tener CRLF final.
- Una fila de encabezado opcional aparece como primera línea.
- Los campos pueden estar entre comillas dobles.
- Los campos que contengan comas, comillas dobles o saltos de línea deben estar entre comillas dobles.
- Una comilla doble dentro de un campo se escapa duplicándola:
"". - Los espacios se consideran parte del campo y no deben ignorarse.
"id","nombre","precio","descripcion"
1,"Laptop","999.99","Pantalla de 15"" alta resolución"
2,"Ratón","29.99","Ergonómico, inalámbrico"
3,"Teclado","79.99","Mecánico
clicky"
TSV — Valores Separados por Tabuladores
TSV usa un carácter de tabulador (\t, U+0009) como delimitador. Los tabuladores son raros en los datos de texto, por lo que TSV evita la mayoría de los requisitos de entrecomillado:
id nombre precio descripcion
1 Laptop 999.99 Pantalla 15" alta resolución
2 Ratón 29.99 Ergonómico inalámbrico
TSV es producido nativamente al copiar celdas de Excel o Google Sheets y pegarlas en un editor de texto. Es preferido para datos de bioinformática (formatos FASTQ, BED, GFF) y pipelines de comandos Unix.
Desventaja: TSV falla silenciosamente si algún valor de datos contiene un tabulador. CSV con entrecomillado adecuado maneja los tabuladores bien.
Problemas de Codificación
Los archivos CSV no tienen cabecera para declarar la codificación. El mismo byte 0xE9 significa é en ISO-8859-1 pero es parte de una secuencia multibyte en UTF-8.
| Problema | Causa | Solución |
|---|---|---|
| Caracteres acentuados distorsionados | Incompatibilidad de codificación (UTF-8 vs Latin-1) | Siempre guardar y leer como UTF-8 |
Prefijo BOM  |
UTF-8 BOM (EF BB BF) mostrado como texto |
Eliminar BOM o usar UTF-8-sin-BOM |
| Excel no reconoce UTF-8 | Excel espera BOM UTF-8 | Añadir BOM o usar UTF-16 LE para Excel |
| Finales de línea incorrectos | Unix LF vs Windows CRLF | Normalizar con dos2unix / unix2dos |
Análisis Correcto de CSV
Nunca dividas por comas con un simple split(',') — esto falla con campos entrecomillados. Usa una librería CSV adecuada:
Python:
import csv
with open('datos.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for fila in reader:
print(fila['nombre'], fila['precio'])
PHP:
if (($fh = fopen('datos.csv', 'r')) !== false) {
$cabecera = fgetcsv($fh);
while (($fila = fgetcsv($fh)) !== false) {
$registro = array_combine($cabecera, $fila);
echo $registro['nombre'];
}
}
pandas (Python):
import pandas as pd
df = pd.read_csv('datos.csv', encoding='utf-8', dtype={'id': int, 'precio': float})
print(df.describe())
Inferencia de Tipos — Sorpresas Frecuentes
CSV no tiene tipos incorporados — todo valor es una cadena. La inferencia de tipos se realiza en tiempo de lectura:
| Valor bruto | Excel interpreta como | pandas interpreta como |
|---|---|---|
1/2 |
2 de enero (fecha) | cadena "1/2" |
0001 |
entero 1 (pierde ceros iniciales) |
cadena "0001" (con dtype=str) |
TRUE |
booleano True |
booleano True |
1E5 |
100000 (número) |
float 100000.0 |
NA |
cadena "NA" |
float NaN |
Soluciones: declarar tipos explícitamente al leer, usar Frictionless Data Specs o CSVW para documentar tipos de columnas.
Dialectos CSV
| Dialecto | Separador | Comillas | Notas |
|---|---|---|---|
| RFC 4180 | , |
" |
Base oficial |
| Excel CSV | , |
" |
Añade BOM UTF-8, CRLF |
| Excel CSV Europeo | ; |
" |
Punto y coma para locales con coma decimal |
| MySQL CSV | , |
" |
NULL representado como \N |
| PostgreSQL COPY | \t |
" |
Similar a TSV |
| LibreOffice Calc | ; |
" |
Por defecto en muchos locales de la UE |
CSV para Archivos Grandes
Para archivos superiores a ~1 GB:
- Procesar fila por fila — nunca cargar todo en memoria.
- DuckDB: SQL directamente sobre archivos CSV sin configuración:
SELECT nombre, AVG(precio) FROM read_csv_auto('datos.csv') GROUP BY nombre; - Convertir a Parquet: 5-10× más pequeño, almacenamiento columnar, esquema tipado.
- Apache Spark:
spark.read.csv()con detección automática de particiones. - csvkit: suite de herramientas de línea de comandos (
csvstat,csvcut,csvsql,in2csv).
Conversión de CSV
- CSV → JSON:
csvkit'scsvjson, pandasdf.to_json(orient='records'). - CSV → Parquet:
pandas+pyarrow, o DuckDBCOPY TO 'salida.parquet' (FORMAT PARQUET). - CSV → SQL:
csvsql --db sqlite:///datos.db --insert datos.csv. - CSV → Excel:
pandasto_excel(), oopenpyxldirectamente. - JSON → CSV:
pandasjson_normalize()+to_csv(), ojq+@csv. - XML → CSV: XSLT, o Python
xmltodict+ pandas.
Buenas Prácticas
- Especifica siempre la codificación — UTF-8 sin BOM para pipelines Unix; UTF-8 con BOM si el destinatario es Excel en Windows.
- Entrecomilla todos los campos de cadena que puedan contener el delimitador, comillas o saltos de línea.
- Incluye siempre una fila de encabezado con nombres de columna descriptivos.
- Documenta el dialecto en metadatos adjuntos o un README.
- Evita saltos de línea incrustados en valores de campo si la herramienta aguas abajo no los maneja.
- Usa una representación consistente de NULL — cadena vacía,
\N,NULLoNA; documenta cuál. - Valida con un esquema (Frictionless Data, CSVW) antes de la ingesta.
- Convierte a Parquet para cualquier conjunto de datos > 100 MB que se consultará repetidamente.
- Usa TSV para datos de bioinformática donde los tabuladores nunca aparecen en los valores.
- Nunca analices CSV con regex o
split— usa una librería CSV adecuada.
Conversiones relacionadas
Conversiones de documento que siguen este tema: