Crear un diccionario de datos con significados, unidades, tipos y valores permitidos
Documenta qué significa cada columna del conjunto de datos antes del análisis, incluida su unidad, tipo de dato y valores permitidos. Un pequeño conjunto de datos sintético muestra cómo el mismo diccionario también puede servir para una validación automática sencilla.
Contenido revisado 2026.09.20Incluye código 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 esEsta guía está dirigida a investigadores que necesitan una descripción clara, columna por columna, de un conjunto de datos que otras personas puedan leer y revisar.
Preparación
Python 3.12 y un comando de terminal que inicie esa versión.
Un editor de texto o programa de hojas de cálculo que pueda guardar archivos CSV en UTF-8.
Una carpeta de trabajo donde el script pueda crear una nueva carpeta dentro de outputs.
Solo se requiere la biblioteca estándar de Python: csv, pathlib y re.
01Tratar el diccionario de datos como parte del conjunto de datos
El nombre de una columna rara vez basta para describir datos de investigación. speed podría significar velocidad del vehículo, velocidad de la rueda o velocidad angular. accel podría significar aceleración longitudinal, lateral o total. Un diccionario de datos registra el significado previsto para que los análisis posteriores no dependan de suposiciones.
Este tutorial registra seis elementos de información para cada columna: nombre de la columna, significado, unidad, tipo de dato, valores permitidos y un ejemplo. El campo de valores permitidos puede describir categorías, rangos numéricos, reglas de unicidad o patrones de texto simples.
02Crear un pequeño conjunto de datos sintético de investigación
El siguiente conjunto de datos es sintético y fue creado específicamente para este artículo. Guárdalo como test_runs.csv. Cuatro filas siguen las reglas previstas. La quinta fila contiene deliberadamente cuatro problemas para que el diccionario pueda utilizarse como referencia de validación.
Hay 5 filas y 5 columnas. R005 tiene un speed por encima del rango permitido, un valor de acceleration no numérico, una categoría de road-surface no admitida y un valor de test-status no admitido. Su run_id sí es válido.
03Escribir manualmente el diccionario de datos esperado
El diccionario debe poder entenderse sin abrir el código de análisis. Mantén el significado lo bastante específico como para que otro investigador pueda distinguir la columna de otras mediciones similares.
column_name
significado
unidad
tipo
valores permitidos
ejemplo
run_id
Identificador único de una ejecución de prueba
cadena
R seguida de exactamente 3 dígitos; único
R001
speed_kmh
Velocidad del vehículo al inicio del registro
km/h
entero
de 0 a 120 inclusive
50
accel_m_s2
Aceleración longitudinal
m/s^2
decimal
de -5.0 a 5.0 inclusive
-1.2
road_surface
Condición de la superficie de la carretera utilizada en la prueba
categoría
dry;wet
wet
test_status
Estado de revisión del registro de prueba
categoría
complete;review
complete
Una unidad vacía es intencional para identificadores y etiquetas categóricas porque son metadatos adimensionales, no magnitudes físicas medidas. El campo type describe la representación de datos prevista, no lo que una hoja de cálculo pueda inferir automáticamente.
04Generar el diccionario y validar el conjunto de datos
Guarda el siguiente script como data_dictionary_check.py. La especificación de columnas se escribe una sola vez en SPEC. El script exporta esa especificación como data_dictionary.csv y comprueba cada fila con las mismas reglas. El archivo original test_runs.csv solo se lee.
python
import csv
import re
from pathlib import Path
SOURCE = Path("test_runs.csv")
OUTPUT_DIR = Path("outputs") / "data_dictionary_result"
DICTIONARY = OUTPUT_DIR / "data_dictionary.csv"
ISSUES = OUTPUT_DIR / "validation_issues.csv"
SPEC = [
{
"column_name": "run_id",
"meaning": "Unique identifier for one test run",
"unit": "",
"type": "string",
"allowed_values": "R followed by exactly 3 digits; unique",
"example": "R001",
},
{
"column_name": "speed_kmh",
"meaning": "Vehicle speed at the start of the record",
"unit": "km/h",
"type": "integer",
"allowed_values": "0 to 120 inclusive",
"example": "50",
},
{
"column_name": "accel_m_s2",
"meaning": "Longitudinal acceleration",
"unit": "m/s^2",
"type": "float",
"allowed_values": "-5.0 to 5.0 inclusive",
"example": "-1.2",
},
{
"column_name": "road_surface",
"meaning": "Road-surface condition used for the test",
"unit": "",
"type": "category",
"allowed_values": "dry;wet",
"example": "wet",
},
{
"column_name": "test_status",
"meaning": "Review state of the test record",
"unit": "",
"type": "category",
"allowed_values": "complete;review",
"example": "complete",
},
]
def issue(row_number, column, value, problem):
return {
"row_number": row_number,
"column_name": column,
"value": value,
"issue": problem,
}
def main() -> None:
if not SOURCE.is_file():
raise FileNotFoundError(f"Source CSV not found: {SOURCE}")
if OUTPUT_DIR.exists():
raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")
expected_columns = [item["column_name"] for item in SPEC]
issues = []
seen_run_ids = set()
row_count = 0
with SOURCE.open("r", encoding="utf-8-sig", newline="") as stream:
reader = csv.DictReader(stream)
if reader.fieldnames != expected_columns:
raise ValueError(
f"Header mismatch. Expected {expected_columns}, got {reader.fieldnames}."
)
for row_number, row in enumerate(reader, start=2):
row_count += 1
run_id = row["run_id"].strip()
if re.fullmatch(r"R[0-9]{3}", run_id) is None:
issues.append(issue(row_number, "run_id", run_id, "PATTERN_ERROR"))
elif run_id in seen_run_ids:
issues.append(issue(row_number, "run_id", run_id, "DUPLICATE_VALUE"))
seen_run_ids.add(run_id)
try:
speed = int(row["speed_kmh"])
except ValueError:
issues.append(issue(row_number, "speed_kmh", row["speed_kmh"], "TYPE_ERROR"))
else:
if not 0 <= speed <= 120:
issues.append(issue(row_number, "speed_kmh", row["speed_kmh"], "OUT_OF_RANGE"))
try:
accel = float(row["accel_m_s2"])
except ValueError:
issues.append(issue(row_number, "accel_m_s2", row["accel_m_s2"], "TYPE_ERROR"))
else:
if not -5.0 <= accel <= 5.0:
issues.append(issue(row_number, "accel_m_s2", row["accel_m_s2"], "OUT_OF_RANGE"))
if row["road_surface"] not in {"dry", "wet"}:
issues.append(issue(row_number, "road_surface", row["road_surface"], "ALLOWED_VALUE_ERROR"))
if row["test_status"] not in {"complete", "review"}:
issues.append(issue(row_number, "test_status", row["test_status"], "ALLOWED_VALUE_ERROR"))
OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir()
dictionary_fields = [
"column_name", "meaning", "unit", "type", "allowed_values", "example"
]
with DICTIONARY.open("x", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=dictionary_fields)
writer.writeheader()
writer.writerows(SPEC)
issue_fields = ["row_number", "column_name", "value", "issue"]
with ISSUES.open("x", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=issue_fields)
writer.writeheader()
writer.writerows(issues)
print(f"Rows checked: {row_count}.")
print(f"Dictionary columns: {len(SPEC)}.")
print(f"Validation issues: {len(issues)}.")
print(f"Output folder: {OUTPUT_DIR.as_posix()}")
if __name__ == "__main__":
main()
05Comparar los problemas de validación esperados
Solo R005 debería producir problemas. Como el encabezado del CSV ocupa la fila 1, R005 corresponde físicamente a la fila 6 del CSV. Deberían escribirse cuatro filas de problemas.
La salida de consola esperada que aparece a continuación se obtuvo manualmente a partir del conjunto de datos sintético y del script. No es un registro capturado de una ejecución.
06Comprobar que el diccionario y los datos sigan alineados
Confirma que cada columna del conjunto de datos tenga exactamente una fila en el diccionario.
Comprueba que las unidades físicas estén indicadas explícitamente para las magnitudes medidas.
Confirma que los valores categóricos permitidos usen la misma ortografía y capitalización que el conjunto de datos.
Revisa cada problema de validación en lugar de eliminar automáticamente las filas incorrectas.
Ejecuta el script de nuevo sin cambiar OUTPUT_DIR. Debería detenerse con FileExistsError en lugar de sustituir el diccionario y el informe anteriores.
Problema
Qué comprobar
Una nueva columna del conjunto de datos no tiene entrada en el diccionario
Actualiza el diccionario antes del análisis para documentar el significado y la unidad.
El mismo concepto aparece con unidades diferentes
Usa columnas separadas o estandariza las unidades explícitamente; no dependas de la memoria.
Las etiquetas de categoría cambian con el tiempo
Define los valores permitidos y documenta las adiciones intencionadas, como una nueva condición de carretera.
La hoja de cálculo convierte IDs enteros en números
Guarda los identificadores como cadenas cuando los ceros iniciales o los patrones sean significativos.
La validación pasa, pero el significado es incorrecto
Las comprobaciones estructurales no pueden detectar una definición científica incorrecta ni un canal de sensor mal etiquetado.
07Ampliar el diccionario a medida que crece el proyecto
Un diccionario práctico de datos de investigación suele necesitar más que los seis campos mostrados aquí. Según el proyecto, añade source system, sensor location, coordinate direction, sampling rate, nullable status, precision, calculation method, valid range, missing-value code y responsible owner.
Los valores permitidos deben reflejar el significado científico y no simplemente el mínimo y el máximo observados actualmente. Si en un archivo los valores de speed están entre 30 y 70 km/h, eso no significa automáticamente que de 30 a 70 sea el rango de ingeniería válido.
Versiona el diccionario junto con el conjunto de datos o el código de análisis. Si cambia la definición de una columna, una unidad, la convención de signo o una categoría, registra cuándo se produjo el cambio. Un diccionario de datos resulta más útil cuando describe exactamente la versión de los datos que se está analizando.
Registro de ejecución y verificación
ChatGPT Python tool · Python 3.13.5 · standard library: csv, pathlib, re
La ejecución terminó correctamente para 5 filas y 5 columnas del diccionario.
El validation_issues.csv generado contenía exactamente 4 filas, todas correspondientes a la fila física 6 del CSV (R005): speed_kmh 135 OUT_OF_RANGE, accel_m_s2 fast TYPE_ERROR, road_surface snow ALLOWED_VALUE_ERROR y test_status done ALLOWED_VALUE_ERROR.
El validation_issues.csv generado coincidió exactamente con el CSV esperado del artículo.
El data_dictionary.csv generado contenía exactamente las 5 filas SPEC y los valores de metadatos esperados.
La salida de consola coincidió exactamente: Rows checked: 5; Dictionary columns: 5; Validation issues: 4; Output folder: outputs/data_dictionary_result.
La segunda ejecución produjo FileExistsError para outputs/data_dictionary_result, confirmando la protección contra sobrescritura.
La comparación SHA-256 confirmó que test_runs.csv permaneció sin cambios.
Límites de la verificación
El entorno de ejecución fue Python 3.13.5 en lugar del Python 3.12 objetivo del artículo.
El entorno de ejecución emitió en stderr una advertencia no relacionada del calentamiento del entorno de hojas de cálculo durante el inicio de Python; no afectó a la primera ejecución correcta del script, a los archivos generados ni a la prueba de protección contra sobrescritura.
El script verifica únicamente las reglas declaradas de estructura, tipo, rango y categoría; no valida la corrección científica de las definiciones de metadatos en sí.
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.
En lugar de recopilar solo un título y una URL, registra en una sola fila la fecha de referencia, la fecha de publicación, la fecha de acceso, las unidades y las condiciones de uso. Incluye una plantilla CSV y una lista de comprobación que no requieren código.
Separa los ID duplicados de las respuestas vacías en 10 respuestas sintéticas. Indica el denominador de respuestas válidas y guarda en un archivo nuevo los recuentos y porcentajes por opción, además de los motivos de exclusión.
Mantén una pequeña lista de referencias de investigación en CSV, normaliza el texto DOI para compararlo y genera un archivo de revisión para valores DOI duplicados o ausentes. El workflow conserva el CSV original y no afirma que un DOI sea válido solo porque esté presente.