En el extremo simple del continuo de Patrones ETL está el formato más común de todos: CSV, o valores separados por comas, y su primo cercano, la hoja de cálculo Excel. Grandes cantidades de datos se mueven en estos formatos - fácilmente compartidos, legibles para humanos - ¿qué no gustar en ArcGIS? Bueno, ¡estas cosas!
- No hay un esquema adecuado incorporado en el formato
- Los nombres de columnas a menudo no son válidos en ArcGIS
- Los campos de texto con valores numéricos se tratan como numéricos
- Se asume que los anchos de campo de texto son 8000 (CSV) o 255 (Excel) bytes
- Los campos enteros pueden tratarse como flotantes de doble precisión
- Los valores nulos pueden codificarse con cero u otro valor poco probable
- La geometría a menudo se codifica en un formato no compatible para la creación de clases de entidad
Tome este conjunto de datos popular de data.gov, reflejado desde el portal de datos abiertos de Washington:
Primero, los datos como un mapa:
Washington EV Population
Ahora el archivo CSV fuente:
Problemas con Datos CSV o Excel
En rojo estoy señalando algunas de estas violaciones usuales sospechosas. Los nombres de columnas tienen espacios o metacaracteres, los códigos postales USPS pueden tener ceros a la izquierda por lo que deberían ser texto, ceros se han usado para codificar nulos en las columnas Electric Range y Base MSRP, Vehicle Location está en formato WKT y 2020 Census Tract tiene enteros grandes y un nombre que comienza con un número.
El conjunto de datos tiene velocidad - se actualiza regularmente - así que si te interesa usarlo, o cualquiera de los miles similares - querrás automatizar el manejo de estos problemas con geoprocesamiento.
Primero, ¡algo de investigación! En la descarga del blog hay una herramienta script que usé para escanear el archivo CSV buscando anchos máximos de datos, aquí está el código:
tbl = arcpy.GetParameterAsText(0)
d = arcpy.da.Describe(tbl)
flds = [f.name for f in d['fields'] if f.type == 'String']
mDict = {f:0 for f in flds}
with arcpy.da.SearchCursor(tbl,flds) as cursor:
for row in cursor:
for f in flds:
if row[flds.index(f)]:
mDict[f] = max(mDict[f],len(row[flds.index(f)]))
for k in mDict.keys():
arcpy.AddMessage(f"""El campo '{k}' en la tabla de entrada '{tbl}' tiene un ancho máximo de datos '{mDict[k]}'""")
Esto produce:
Anchos Máximos de Campos de Texto
Ignorando la columna Postal Code, que el conocimiento local me dice que tiene 5 caracteres de ancho, ahora puedo ver los anchos requeridos por cada campo de texto.
Ahora estoy en posición para diseñar un esquema que maneje correctamente el archivo en cuestión. Elegí ModelBuilder para persistir mi procesamiento ya que puede envolver funciones centrales de geoprocesamiento y Python que planeo usar. El modelo terminado es este, que recorreremos.
Modelo EVPopulation
Lo primero es imponer un esquema diseñado. Esto se hace usando el control field map en Export Table, básicamente copiando los datos a una tabla en memoria con el esquema deseado. El control Field Map te permite renombrar, convertir e incluso construir campos muy flexiblemente.
En este caso solo hay un campo fuente para cada campo de salida, así que la Acción es siempre First, y solo se manipulan las propiedades del campo.
Mapa de Campos
A continuación del Export Table, la clase de entidad salida se crea usando la tabla en memoria como plantilla, se agregan filas (aún sin geometría), luego se crea la geometría desde la columna WKT y los dos campos con nulos codificados con cero se corrigen con herramientas Calculate Field (nota el procesamiento condicional). Finalmente, el campo Vehicle Location se elimina por ser redundante.
¿Hemos terminado? No. La mejor práctica es la automatización completa, y estos datos vienen desde la web.
La URL usada para descargar el archivo no es válida como entrada Text File para geoprocesamiento como quiere el modelo. También existe el riesgo que un usuario use un archivo CSV con un nombre diferente a Electric_Vehicle_Population_Data.csv, lo cual haría que el field map en Export Table vuelva al manejo predeterminado de campos, deshaciendo todo nuestro trabajo en diseño del esquema.
Para manejar tanto entrada web como nombre consistente del archivo, el modelo EVPopulation está envuelto en un modelo padre, URL2EVPopulation:
URL2EVPopulation
Descarga Web
Primero una herramienta modelo Calculate Value descarga los datos actuales a un archivo nombrado consistentemente y del tipo parámetro Text File, luego se llama al modelo EVPopulation para procesar los datos. ¿Ves cómo un fragmento muy simple en Python se encarga de la automatización? 😉
Ahora tenemos manejo automatizado del archivo CSV. Estiré un poco el concepto de "archivos locales bien conocidos", alcanzando a la web por datos, pero hoy en día los archivos a través del internet sí son locales. Puedo programar o ejecutar manualmente URL2EVPopulation cuando quiera.
Los modelos y la herramienta script están en la descarga del blog.