I am trying to create a parsing function that will generate the Date and Time of METAR reports which contain 6 hourly weather information. Based on the research I have done, I have found a parsing function that will do what I am trying to accomplish:
For clarity, the METAR parsing code is the following:
import pandas as pd import numpy as np import seaborn as sns import DateTime Training_METAR = pd.read_csv("KBOS Boston Training Metar Data.csv") Test_METAR = pd.read_csv("KBOS Test METAR Data.csv") np.random.seed(0) # print(Training_METAR['valid'].head()) Training_METAR["Dates_Needed"] = pd.to_datetime(Training_METAR["valid"], format="%m/%d/%Y %H:%M") print(Training_METAR["Dates_Needed"].head())While I am sure that this is the parsing function that I need, I am somewhat unsure where I can implement this function into my METAR parsing code. I have tried this function in multiple sections of the METAR parsing code (separate copies to ensure the original stays intact), but I am unsure where I can place it within the code that would allow for the proper parsing of the Dates and times for the reports I need.
For clarity, the METAR parsing code is the following:
import os import pathlib # get your own relative path import pandas as pd from lazyme.string import color_print import csv # included in python 3.8.2 install import numpy as np import tkinter as tk from tkinter import filedialog import seaborn as sns import datetime count = 1 # this is an example string from the decoder doc with added fields # exampleData = "METAR KABC 121755Z AUTO 21016G24KT 180V240 1SM R11/P6000FT -RA " \ # "BR BKN015 OVC025 06/04 A2990 RMK AO2 PK WND 20032/25 WSHFT 1715 " \ # "VIS 3/4V1 1/2 VIS 3/4 RWY11 RAB07 CIG 013V017 CIG 017 RWY11 " \ # "PRESFR SLP125 P0003 60009 70015 T00640036 10066 21012 400461006 " \ # "58033 TSNO $" class MetarDataObj(object): """ A Metar Object contains only the data that is decoded from a single metar string. """ """ The contents of the example data and their field labels METAR - TYPE OF REPORT KABC - STATION IDENTIFIER 121755Z - DATE/TIME AUTO - REPORT MODIFIER 21016G24KT 180V240 - WIND DIRECTION AND SPEED 1SM - VISIBILITY R11/P6000FT - RUNWAY VISUAL RANGE -RA BR - WEATHER PHENOMENA BKN015 OVC025 - SKY CONDITION 06/04 - TEMPERATURE/DEW POINT A2990 - ALTIMETER RMK - REMARK - TORNADIC ACTIVITY AO2 - TYPE OF AUTOMATED STATION PK WND 20032/25 - PEAK WIND WSHFT 1715 - WIND SHIFT - TOWER OR SURFACE VISIBILITY VIS 3/4V1 1/2 - VARIABLE PREVAILING VISIBILITY VIS 3/4 RWY11 - VISIBILITY AT SECOND LOCATION - LIGHTNING RAB07 - BEGINNING AND ENDING OF PRECIPITATION AND THUNDERSTORM CIG 013V017 - VIRGA CIG 017 RWY11 - VARIABLE CEILING HEIGHT PRESFR - PRESSURE RISING OR FALLING RAPIDLY SLP125 - SEA-LEVEL PRESSURE P0003 - HOURLY PRECIPITATION AMOUNT 60009 - 3- AND 6-HOUR PRECIPITATION AMOUNT ** want this - 24-HOUR PRECIPITATION AMOUNT ** want this T00640036 - HOURLY TEMPERATURE AND DEW POINT 10066 - 6-HOUR MAXIMUM TEMPERATURE ** want this 21012 - 6-HOUR MINIMUM TEMPERATURE ** want this - 24-HOUR MAXIMUM AND MINIMUM TEMPERATURE ** want this 58033 - PRESSURE TENDENCY TSNO - SENSOR STATUS INDICATORS $ - MAINTENANCE CHECK INDICATOR """ # class constructor def __init__(self, metarString): # class local variables, initialized to nothing self.precip6 = None self.temp6max = None self.temp6min = None self.time = None # call function to parse data, pass string from constructor # handle empty construction if metarString != None: self.parseCSVdata(metarString) # process metar data def parseCSVdata(self, aString): """ Here we will parse the metar string passed into the default constructor. """ # the field named 'SEA-LEVEL PRESSURE' is the stake in the ground. # stripping off everything before this field, packing into a list tinyMetar = aString[aString.find("SLP"): -1].split() # remove the stake # color_print('\tSpreadsheet row' + str(count) + '\n', color="red") # an empty list looks like [] # handling the case where a row does not have a stake in the ground if len(tinyMetar) != 0: # Loop over contents looking for data, skipping over the stake for metarField in tinyMetar: # look for 6 hour precip if metarField[0] == "6" and len(metarField) == 5: # get the 6 hour if metarField[1:] == "////": self.precip6 = None else: self.precip6 = float(metarField[3:]) * .01 elif metarField[0] == "T" and len(metarField) == 9: continue # look for 6 hour max elif metarField[0] == "1" and len(metarField) == 5: # custom exception handling # try to catch improper field if metarField[1:] == "////": self.temp6max = None else: try: float(metarField) # try to do this but don't die if # fails t6minSign = None # get the sign of max if metarField[1] == "0": # positive temp t6minSign = "" else: # negative temp t6minSign = "-" # get 6 hr max self.temp6max = float( t6minSign + metarField[2] + "." + metarField[3:]) except ValueError: # if it fails come down here and do this continue # look for 6 hour min elif metarField[0] == "2" and len(metarField) == 5: t6minSign = None # get the sign of min if metarField[1:] == "////": self.temp6min = None else: if metarField[1] == "0": # positive temp t6minSign = "" else: # negative temp t6minSign = "-" # get 6 hr min self.temp6min = float(t6minSign + metarField[2] + "." + metarField[3:]) # color_print("\trow skipped", color="yellow")