4 votos

Limpieza de datos en Excel para uso en QGIS

Estoy tratando de limpiar un grande .txt conjunto de datos en Excel. Creo que una macro o de otra aplicación puede ser capaz de limpiar los datos de la manera en que yo quiero, pero tengo limitados conocimientos de programación. Necesito crear campos de diferentes secciones en el .archivo txt para poder luego de geocodificación de los puntos. Estoy llevando a cabo un análisis de los delitos para mi departamento de policía local y hasta ahora he estado usando comodines y el Buscar Y Reemplazar herramienta para hacer esto, pero tengo casi 2 años el valor de las llamadas a la policía. Los campos necesarios:"Direccion", "Ciudad", "Estado", "Tipo", "Ubicación", "Fecha", "el Día de la Semana", "Recibido", "Enviado", "Llegó la Hora", "Tiempo Liberado". Puse los datos de enero de 2012 en Github en la repo llamado SLO-Crimen bajo mi nombre, chadbunn. Voy a estar usando CartoDB para geocodificar los datos y, a continuación, QGIS para realizar el análisis. Probablemente voy a hacer algunos mapas en TileMill así si tengo el tiempo suficiente para. El aporte se agradece porque se está volviendo tedioso! Gracias!

https://github.com/chadbunn/SLO-Crime/tree/master

Texto de ejemplo a continuación muestra un solo incidente (archivo de texto sin formato, cada sección se compone de un despacho encabezado resumen seguido por el tipo / dirección / oficial y otra información):

===============================================================================                             
120101001 01/01/12 Received:00:05 Dispatched:00:06 Arrived:00:12 Cleared:00:53                              
===============================================================================                             
Type: MENTAL SUBJ                                             Location:LZ1                              
As Observed:                                
      Mental Health                             

Addr: 1257 RICH, San Luis Obispo, CA             Clearance Code:Report Filed in                             

Responsible Officer: Hyman, J                               
Units: 4235  ,4241                              
 Des: incid#=120101001 AP/KAVANAGH,KOLLEEN 060455 166 PC clr:RTF oc:MENH call=1l

5voto

aditya Puntos 111

Una de las grandes cosas sobre el texto estructurado como esta (generalmente de ancho fijo) es que es bastante fácil de analizar mediante un lenguaje de programación. He utilizado casi el mismo enfoque que @congrene utilizado, pero yo lo escribí con Python, que es ampliamente utilizado en el sistema de información geográfica de la comunidad.

Tenga en cuenta que, en muchos casos, la Ciudad y el Estado no están completamente llenos. Por lo tanto yo (y @congrene) codificada de la Ciudad y el Estado de los atributos. Si estaban completamente lleno, se podrían extraer la ciudad con record["city"] = parseaddress[1] y el estado con record["state"] = parseaddress[2].

Con fines explicativos de cómo funciona el código, he creado un diccionario de Python (record) y, a continuación, añade nuevos key:value parejas para celebrar cada atributo individual. Entonces agregué el "registro" como un elemento de la Lista de Python, el cual podría ser utilizado para el bucle a través de todos los registros cuando llegó el tiempo para escribir a CSV. Que hizo más fácil para construir el CSV con sólo llamar 1) el siguiente registro y 2) la clave correcta:el valor para el registro cuando se escribe el resultado en el archivo CSV.

import os, datetime, csv

infile = r'd:\path_to_your_data\January_Data.txt'
outfile = r'd:\path_to_your_data\January_Data.csv'

#Create an list aggregator to hold all csv values
csv_data = []

with open(infile) as f:
    for line in f.readlines():  ##read through each line in the file

        #Look for keywords in a line and extract the data that follows it
        if "Received:" in line:
            record = {}  ##create a dictionary to hold incident-level data
            record["incident"] = line[0:9].strip()
            record["date"] = line[10:18].strip()
            record["dayofweek"] = datetime.datetime.strptime(record["date"],'%m/%d/%y').strftime('%A')
            record["received"] = line[28:33].strip()
            record["dispatched"] = line[45:50].strip()
            record["arrived"] = line[59:64].strip()
            record["cleared"] = line[73:80].strip()

        elif "Type:" in line:
            record["type"] = line[6:20].strip()
            record["location"] = line[71:80].strip()

        elif "Addr:" in line:
            parseaddress = line[6:49].strip().split(",")
            record["addr"] = parseaddress[0]
            record["city"] = "San Luis Obispo"
            record["state"] = "CA"
            record["clearcode"] = line[64:80].strip()

        elif "Responsible Officer:" in line:
            record["officer"] = line[21:80].strip()

        elif "Units:" in line:
            record["units"] = line[6:80].strip()

        elif "Des:" in line:
            ##This line appears to terminate an incident record
            csv_data.append(record)


if os.path.exists(outfile):  ##check to see if the output exists already
    os.remove(outfile)

#Write the data to a CSV file
with open (outfile, 'wb') as csvfile:
    csvwriter = csv.writer(csvfile, delimiter=',', quotechar='"')

    #create the header row
    csvwriter.writerow(["Incident","Address", "City", "State", "Type", "Location", "Date", "Day of Week", "Time Received", "Time Dispatched", "Time Arrived", "Time Cleared"])

    #Add individual records to the CSV
    for record in csv_data:
        csvwriter.writerow([ record["incident"], record["addr"], record["city"], record["state"], record["type"], record["location"], record["date"], record["dayofweek"], record["received"], record["dispatched"], record["arrived"], record["cleared"] ])

print "Data converted to :" + str(outfile)

2voto

Sebastian Hoitz Puntos 4533

Dado que los campos que son de su interés se encuentran en 3 diferentes líneas típicas, y dada su falta de habilidades de programación, yo podría sugerir hacer un primer paso en la eliminación de líneas inútiles.

Usted puede ser capaz de hacer eso con un mejor editor de texto. Como ejemplo, el siguiente comando en Vim o GVim va a eliminar todas las líneas que no contienen cualquiera de estas 3 condiciones:

  • 3 o más dígitos al comienzo de la línea (números de registro) (regex patrón: ^\d\d\d\+)
  • Las líneas que comienzan con el Tipo (regex patrón: ^Type)
  • Las líneas que comienzan con Addr (regex patrón: ^Addr)

La magia comando :v/^\d\d\d\+\|^Type\|^Addr/d

luego transformar el archivo en este formato:

Más notas sobre el comando de arriba al final del post

..
120131082 01/31/12 Received:20:48 Dispatched:20:51 etc. 
Type: COLL NON                    Location:LZ2                          
Addr: 297 MADONNA; PANERA BREAD, San Luis Obisp  Clearance Code:Report Filed in
...

Desde allí, usted tendrá que encontrar una manera de unirse a las 3 de la recurrente líneas en una sola. Esto podría ser hecho de manera muy mecánica, búsqueda el VBA de Excel hilos para sugerencias y soluciones que este de aquí acerca de la remodelación es directamente aplicable!. Al menos a partir de ahí, vas a estar más cerca de algo que se puede analizar dentro de Excel. Buena suerte !


Información del complemento en Vim comando:

:v/ some_pattern /d

  1. Que es un "reVerse grep, a continuación, Elimine" de comandos. Como tal, va a eliminar todas las líneas que no coinciden con el patrón entre barras.

  2. Los patrones se encuentran en la expresión regular de forma regex que por CIERTO son compatibles en la mayoría de los lenguajes de programación y los buenos editores de texto. En Vim el caso de la "canalización" de carácter" significado "o" necesita ser escapado con una barra diagonal inversa: \|.

2voto

Om Shankar Puntos 117

Sé que usted pidió una solución con excel, pero aquí hay un pequeño script en ruby para analizar estos datos. Para utilizar, tendrás que instalar ruby (https://www.ruby-lang.org/en/downloads/). Una vez configurado, hay que poner los datos y la secuencia de comandos en la misma carpeta y ejecutar: ruby munge.rb

Mi resultado de la ejecución de este en una porción de la muestra de los datos proporcionados: https://gist.github.com/tomay/ac536aad29cc50c7e06b
(nota: este ejemplo es geocodificar con la excelente ruby geocoder joya, véase el ejemplo de código en la misma esencia de la página)

Yo no he probado esta ampliamente, por lo que usar con cuidado. Preguntar si se encuentra con problemas.

require 'date'
# open files
infile = File.new("January_Data.txt","r")
outfile = File.new("result.csv","w")

# write header
header = "Address,City,State,Type,Location,Date,Day of Week,Time Received,Time Dispatched,Time Arrived,Time Cleared\n"
outfile << header

# read file lines
result = {}
infile.each do |line|
  values = line.split(" ")
  next if (values.length < 2 || line.chomp == "As Observed:")
  begin
    if values[0] == "Addr:"
      result["address"] = line.split(",")[0].gsub("Addr: ","")
    elsif values[0] == "Type:"
      result["location"] = values.pop.split(":").last
      values.shift
      result["type"] = values.join(" ")
    elsif values[2].split(":")[0] == "Received"
      result["date"] = values[1]
      result["day"] = Date.strptime(result['date'], '%m/%d/%y').strftime('%A')
      result["time_received"] = "#{values[2].split(":")[1]}:#{values[2].split(":")[2]}"
      result["time_dispatched"] = "#{values[3].split(":")[1]}:#{values[3].split(":")[2]}"
      result["time_arrived"] = "#{values[4].split(":")[1]}:#{values[4].split(":")[2]}"
      result["time_cleared"] = "#{values[5].split(":")[1]}:#{values[5].split(":")[2]}"
    elsif values[0] == "Des:"
      # write result
      outfile.write "#{result['address']},San Luis Obispo,CA,#{result['type']},#{result['location']},#{result['date']},#{result['day']},#{result["time_received"]},#{result["time_dispatched"]},#{result["time_arrived"]},#{result["time_cleared"]}\n"
      result = {}
    end
  rescue
    puts "Line was: #{line}"
  end
end

# close files
infile.close
outfile.close

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X