Is there a better way to accomplish this? The function determines the Category
for each row based on some conditions. Another set of conditions determines the ChangeGroup
for the row. Not all the conditions are written but it more or less gets the point across. The determination for a ChangeGroup
is made based on a previous row where ChangeGroup == 'BECMG'
.
Data:
MOCK_DATA = [{'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 12:00:00', 'Ending': '2022-02-19 13:00:00', 'WindDirection': 200, 'WindSpeed': 7, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510111', 'Icing': None, 'Altimeter': 30.09, 'Temperature': -2}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 13:00:00', 'Ending': '2022-02-19 14:00:00', 'WindDirection': 200, 'WindSpeed': 8, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510111', 'Icing': None, 'Altimeter': 30.08, 'Temperature': -1}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 14:00:00', 'Ending': '2022-02-19 15:00:00', 'WindDirection': 210, 'WindSpeed': 10, 'WindGust': 15, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510111', 'Icing': None, 'Altimeter': 30.06, 'Temperature': 0}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 15:00:00', 'Ending': '2022-02-19 16:00:00', 'WindDirection': 220, 'WindSpeed': 11, 'WindGust': 20, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520111', 'Icing': None, 'Altimeter': 30.02, 'Temperature': 2}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 16:00:00', 'Ending': '2022-02-19 17:00:00', 'WindDirection': 230, 'WindSpeed': 11, 'WindGust': 20, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 15500.0, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520113', 'Icing': None, 'Altimeter': 30.01, 'Temperature': 4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 17:00:00', 'Ending': '2022-02-19 18:00:00', 'WindDirection': 260, 'WindSpeed': 10, 'WindGust': 23, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SCT', 'CloudBase1': 4500.0, 'CloudCover2': 'BKN', 'CloudBase2': 6000.0, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510111', 'Icing': '620540', 'Altimeter': 30.01, 'Temperature': 6}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 18:00:00', 'Ending': '2022-02-19 19:00:00', 'WindDirection': 290, 'WindSpeed': 15, 'WindGust': 38, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 5000.0, 'CloudCover2': 'BKN', 'CloudBase2': 7500.0, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510118', 'Icing': '620621', 'Altimeter': 29.99, 'Temperature': 7}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 19:00:00', 'Ending': '2022-02-19 20:00:00', 'WindDirection': 290, 'WindSpeed': 18, 'WindGust': 39, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SCT', 'CloudBase1': 6000.0, 'CloudCover2': 'BKN', 'CloudBase2': 8500.0, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520118', 'Icing': '620700', 'Altimeter': 30.0, 'Temperature': 7}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 20:00:00', 'Ending': '2022-02-19 21:00:00', 'WindDirection': 300, 'WindSpeed': 20, 'WindGust': 42, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520111', 'Icing': None, 'Altimeter': 30.06, 'Temperature': 5}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 21:00:00', 'Ending': '2022-02-19 22:00:00', 'WindDirection': 310, 'WindSpeed': 18, 'WindGust': 40, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 6500.0, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520128', 'Icing': None, 'Altimeter': 30.13, 'Temperature': 3}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 22:00:00', 'Ending': '2022-02-19 23:00:00', 'WindDirection': 310, 'WindSpeed': 17, 'WindGust': 39, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520128', 'Icing': None, 'Altimeter': 30.18, 'Temperature': 1}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-19 23:00:00', 'Ending': '2022-02-20 00:00:00', 'WindDirection': 320, 'WindSpeed': 15, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520121', 'Icing': None, 'Altimeter': 30.24, 'Temperature': 0}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 00:00:00', 'Ending': '2022-02-20 01:00:00', 'WindDirection': 320, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510130', 'Icing': None, 'Altimeter': 30.3, 'Temperature': -1}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 01:00:00', 'Ending': '2022-02-20 02:00:00', 'WindDirection': 320, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '520131', 'Icing': None, 'Altimeter': 30.34, 'Temperature': -2}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 02:00:00', 'Ending': '2022-02-20 03:00:00', 'WindDirection': 320, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510130', 'Icing': None, 'Altimeter': 30.38, 'Temperature': -3}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 03:00:00', 'Ending': '2022-02-20 04:00:00', 'WindDirection': 320, 'WindSpeed': 11, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False,'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.4, 'Temperature': -3}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 04:00:00', 'Ending': '2022-02-20 05:00:00', 'WindDirection': 320, 'WindSpeed': 9, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.42, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 05:00:00', 'Ending': '2022-02-20 06:00:00', 'WindDirection': 320, 'WindSpeed': 7, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.44, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 06:00:00', 'Ending': '2022-02-20 07:00:00', 'WindDirection': 320, 'WindSpeed': 6, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.45, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 07:00:00', 'Ending': '2022-02-20 08:00:00', 'WindDirection': 320, 'WindSpeed': 6, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.46, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 08:00:00', 'Ending': '2022-02-20 09:00:00', 'WindDirection': 320, 'WindSpeed': 5, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510140', 'Icing': None, 'Altimeter': 30.45, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 09:00:00', 'Ending': '2022-02-20 10:00:00', 'WindDirection': 320, 'WindSpeed': 4, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.45, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 10:00:00', 'Ending': '2022-02-20 11:00:00', 'WindDirection': 310, 'WindSpeed': 2, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.46, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 11:00:00', 'Ending': '2022-02-20 12:00:00', 'WindDirection': 280, 'WindSpeed': 1, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.48, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 12:00:00', 'Ending': '2022-02-20 13:00:00', 'WindDirection': 170, 'WindSpeed': 1, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.49, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 13:00:00', 'Ending': '2022-02-20 14:00:00', 'WindDirection': 130, 'WindSpeed': 2, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.5, 'Temperature': -4}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 14:00:00', 'Ending': '2022-02-20 15:00:00', 'WindDirection': 110, 'WindSpeed': 3, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.5, 'Temperature': -3}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 15:00:00', 'Ending': '2022-02-20 16:00:00', 'WindDirection': 170, 'WindSpeed': 2, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.52, 'Temperature': -2}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 16:00:00', 'Ending': '2022-02-20 17:00:00', 'WindDirection': 200, 'WindSpeed': 5, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.51, 'Temperature': 0}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 17:00:00', 'Ending': '2022-02-20 18:00:00', 'WindDirection': 200, 'WindSpeed': 7, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.49, 'Temperature': 1}, {'ChangeGroup': None, 'Category': None, 'Beginning': '2022-02-20 18:00:00', 'Ending': '2022-02-20 19:00:00', 'WindDirection': 190, 'WindSpeed': 8, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SKC', 'CloudBase1': None, 'CloudCover2': None, 'CloudBase2': None, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': None, 'Altimeter': 30.44, 'Temperature': 2}]
Data2
Another data with more changes to Category
due to cloud cover. Sorry I'm working in slightly different environments. This set does not have the ChangeGroup
and Category
included
MOCK_DATA2 = [{'Beginning': '2022-02-03 06:00:00', 'Ending': '2022-02-03 07:00:00', 'WindDirection': 10, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 1500, 'CloudCover2': 'OVC', 'CloudBase2': 2100, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '600197', 'Altimeter': 30.25, 'Temperature': -7}, {'Beginning': '2022-02-03 07:00:00', 'Ending': '2022-02-03 08:00:00', 'WindDirection': 10, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.26, 'Temperature': -8}, {'Beginning': '2022-02-03 08:00:00', 'Ending': '2022-02-03 09:00:00', 'WindDirection': 0, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.27, 'Temperature': -8}, {'Beginning': '2022-02-03 09:00:00', 'Ending': '2022-02-03 10:00:00', 'WindDirection': 10, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.25, 'Temperature': -8}, {'Beginning': '2022-02-03 10:00:00', 'Ending': '2022-02-03 11:00:00', 'WindDirection': 0, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.25, 'Temperature': -8}, {'Beginning': '2022-02-03 11:00:00', 'Ending': '2022-02-03 12:00:00', 'WindDirection': 10, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.25, 'Temperature': -8}, {'Beginning': '2022-02-03 12:00:00', 'Ending': '2022-02-03 13:00:00', 'WindDirection': 10, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650138', 'Altimeter': 30.28, 'Temperature': -7}, {'Beginning': '2022-02-03 13:00:00', 'Ending': '2022-02-03 14:00:00', 'WindDirection': 10, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650138', 'Altimeter': 30.28, 'Temperature': -7}, {'Beginning': '2022-02-03 14:00:00', 'Ending': '2022-02-03 15:00:00', 'WindDirection': 20, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650138', 'Altimeter': 30.28, 'Temperature': -7}, {'Beginning': '2022-02-03 15:00:00', 'Ending': '2022-02-03 16:00:00', 'WindDirection': 10, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650138', 'Altimeter': 30.28, 'Temperature': -6}, {'Beginning': '2022-02-03 16:00:00', 'Ending': '2022-02-03 17:00:00', 'WindDirection': 20, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 1500, 'CloudCover2': 'OVC', 'CloudBase2': 2200, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650197', 'Altimeter': 30.27, 'Temperature': -6}, {'Beginning': '2022-02-03 17:00:00', 'Ending': '2022-02-03 18:00:00', 'WindDirection': 20, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2200.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650197', 'Altimeter': 30.26, 'Temperature': -5}, {'Beginning': '2022-02-03 18:00:00', 'Ending': '2022-02-03 19:00:00', 'WindDirection': 20, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '650197', 'Altimeter': 30.24, 'Temperature': -5}, {'Beginning': '2022-02-03 19:00:00', 'Ending': '2022-02-03 20:00:00', 'WindDirection': 20, 'WindSpeed': 15, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1400, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510121', 'Icing': '650197', 'Altimeter': 30.22, 'Temperature': -5}, {'Beginning': '2022-02-03 20:00:00', 'Ending': '2022-02-03 21:00:00', 'WindDirection': 20, 'WindSpeed': 15, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1400, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510121', 'Icing': '650197', 'Altimeter': 30.21, 'Temperature': -5}, {'Beginning': '2022-02-03 21:00:00', 'Ending': '2022-02-03 22:00:00', 'WindDirection': 20, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1400, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510121', 'Icing': '650197', 'Altimeter': 30.22, 'Temperature': -5}, {'Beginning': '2022-02-03 22:00:00', 'Ending': '2022-02-03 23:00:00', 'WindDirection': 20, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1400, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650197', 'Altimeter': 30.23, 'Temperature': -5}, {'Beginning': '2022-02-03 23:00:00', 'Ending': '2022-02-04 00:00:00', 'WindDirection': 20, 'WindSpeed': 14, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '650197', 'Altimeter': 30.24, 'Temperature': -5}, {'Beginning': '2022-02-04 00:00:00', 'Ending': '2022-02-04 01:00:00', 'WindDirection': 20, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2100.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '620197', 'Altimeter': 30.26, 'Temperature': -5}, {'Beginning': '2022-02-04 01:00:00', 'Ending': '2022-02-04 02:00:00', 'WindDirection': 20, 'WindSpeed': 13, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2200.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '620197', 'Altimeter': 30.27, 'Temperature': -5}, {'Beginning': '2022-02-04 02:00:00', 'Ending': '2022-02-04 03:00:00', 'WindDirection': 20, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': '-SN', 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2200.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '620197', 'Altimeter': 30.27, 'Temperature': -6}, {'Beginning': '2022-02-04 03:00:00', 'Ending': '2022-02-04 04:00:00', 'WindDirection': 20, 'WindSpeed': 12, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 1500, 'CloudCover2': 'OVC', 'CloudBase2': 2200, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': '510131', 'Icing': '620207', 'Altimeter': 30.28, 'Temperature': -6}, {'Beginning': '2022-02-04 04:00:00', 'Ending': '2022-02-04 05:00:00', 'WindDirection': 10, 'WindSpeed': 11, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 1500, 'CloudCover2': 'OVC', 'CloudBase2': 2200, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620207', 'Altimeter': 30.29, 'Temperature': -6}, {'Beginning': '2022-02-04 05:00:00', 'Ending': '2022-02-04 06:00:00', 'WindDirection': 10, 'WindSpeed': 11, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2200.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620207', 'Altimeter': 30.29, 'Temperature': -6}, {'Beginning': '2022-02-04 06:00:00', 'Ending': '2022-02-04 07:00:00', 'WindDirection': 10, 'WindSpeed': 10, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'FEW', 'CloudBase1': 800, 'CloudCover2': 'BKN', 'CloudBase2': 1500, 'CloudCover3': 'OVC', 'CloudBase3': 2200.0, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620207', 'Altimeter': 30.28, 'Temperature': -7}, {'Beginning': '2022-02-04 07:00:00', 'Ending': '2022-02-04 08:00:00', 'WindDirection': 0, 'WindSpeed': 9, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SCT', 'CloudBase1': 800, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620207', 'Altimeter': 30.29, 'Temperature': -7}, {'Beginning': '2022-02-04 08:00:00', 'Ending': '2022-02-04 09:00:00', 'WindDirection': 350, 'WindSpeed': 10, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 900, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620138', 'Altimeter': 30.31, 'Temperature': -7}, {'Beginning': '2022-02-04 09:00:00', 'Ending': '2022-02-04 10:00:00', 'WindDirection': 350, 'WindSpeed': 10, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 900, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620138', 'Altimeter': 30.32, 'Temperature': -8}, {'Beginning': '2022-02-04 10:00:00', 'Ending': '2022-02-04 11:00:00', 'WindDirection': 350, 'WindSpeed': 9, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 900, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620138', 'Altimeter': 30.33, 'Temperature': -8}, {'Beginning': '2022-02-04 11:00:00', 'Ending': '2022-02-04 12:00:00', 'WindDirection': 340, 'WindSpeed': 8, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'BKN', 'CloudBase1': 900, 'CloudCover2': 'OVC', 'CloudBase2': 1500, 'CloudCover3': None, 'CloudBase3': None, 'CloudCover4': None, 'CloudBase4': None, 'CloudCover5': None, 'CloudBase5': None, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620138', 'Altimeter': 30.35, 'Temperature': -8}, {'Beginning': '2022-02-04 12:00:00', 'Ending': '2022-02-04 13:00:00', 'WindDirection': 350, 'WindSpeed': 8, 'WindGust': None, 'Visibility': 9999, 'Precipitation': None, 'Obscuration': None, 'Other': None, 'TSFlag': False, 'CloudCover1': 'SCT', 'CloudBase1': 900, 'CloudCover2': 'SCT', 'CloudBase2': 1500, 'CloudCover3': 'BKN', 'CloudBase3': 2900.0, 'CloudCover4': 'BKN', 'CloudBase4': 6500.0, 'CloudCover5': 'OVC', 'CloudBase5': 9000.0, 'WSHeight': None, 'WSDirection': None, 'WSSpeed': None, 'Turbulence': None, 'Icing': '620801', 'Altimeter': 30.35, 'Temperature': -9}]
Edit 1:
I've started to move some of the conditions out of the for loop and into more vectorized / list comprehension solutions
def dev_mock(taf: pd.DataFrame):
"""\
applies the ammendment & specification criteria
"""
...
taf.loc[0, 'ChangeGroup'] = 'BECMG'
taf['MaxWind'] = taf[['WindSpeed', 'WindGust']].max(axis=1)
cover, bases = taf[pd.Index(CLOUD_COVER)], taf[pd.Index(CLOUD_BASE)]
cover = ((cover == 'BKN') | (cover == 'OVC'))
cover.columns = bases.columns
taf['MinCig'] = bases[cover].min(axis=1)
taf['Category'] = [criteria.loc[
(cig >= criteria['ceiling']) & (vis >= criteria['visibility'])
].index.max() for cig, vis in zip(taf.MinCig, taf.Visibility)]
...
Edit 2:
My attempt to implement the itertools.accumulate
functools.reduce
function. In the first instance I generate a new DataFrame
as the accumulator from rows 0 & 1 and return that DataFrame
as the accumulator
.
...
def accumulator_funk(acc, row) -> pd.DataFrame:
if not isinstance(acc, pd.DataFrame): # first instance
df = pd.DataFrame(
[acc, row]).set_index('Index')
df.loc[row.Index, 'ChangeGroup'] = 'BECMG' if acc.Category != row.Category else None
return df
acc.loc[row.Index, 'Category'] = row.Category
predom = acc.loc[acc.ChangeGroup == 'BECMG'].iloc[-1]
acc.loc[row.Index, 'ChangeGroup'] = (
'BECMG' if predom.Category != row.Category else None)
return acc
# dfs = itertools.accumulate(
# taf[['Category', 'ChangeGroup']].itertuples(), accumulator_funk)
# fcst = ([df for df in dfs][-1])
# more appropriate solution
fcst = functools.reduce(
accumulator_funk, taf[['Category', 'ChangeGroup']].itertuples())
print(fcst)
Out: MOCK_DATA2
Category ChangeGroup
Index
0 D BECMG
1 C BECMG
2 C None
3 C None
4 C None
5 C None
6 C None
7 C None
8 C None
9 C None
10 D BECMG
11 D None
12 D None
13 D None
14 D None
15 D None
16 D None
17 D None
18 D None
19 D None
20 D None
21 D None
22 D None
23 D None
24 D None
25 D None
26 C BECMG
27 C None
28 C None
29 C None
30 E BECMG
Original Solution:
import pandas as pd
import numpy as np
CRITERIA = {
'ceiling': [2000, 1000, 500, 200, 100],
'visibility': [4800, 3200, 3200, 1600, 800],
'index': ['E', 'D', 'C', 'B', 'A']
}
CLOUD_COVER = (
'CloudCover1',
'CloudCover2',
'CloudCover3',
'CloudCover4',
'CloudCover5'
)
CLOUD_BASE = (
'CloudBase1',
'CloudBase2',
'CloudBase3',
'CloudBase4',
'CloudBase5'
)
CLOUD_GROUP = np.stack((CLOUD_COVER, CLOUD_BASE), axis=1).flatten()
def dev_mock(taf: pd.DataFrame):
"""\
applies the ammendment & specification criteria
"""
criteria = pd.DataFrame(CRITERIA).set_index(
'index').rename_axis('Category')
def lowest_bkn_or_ovc_height(taf_row: pd.Series) -> int:
ceiling = ((taf_row[pd.Index(CLOUD_COVER)] == 'OVC') | (
taf_row[pd.Index(CLOUD_COVER)] == 'BKN'))
if ceiling.any():
return np.nanmin(np.where(
ceiling, taf_row[pd.Index(CLOUD_BASE)], np.nan)
)
return 2000
def max_wind(taf_series: pd.Series) -> int:
return np.max(taf_series[['WindSpeed', 'WindGust']])
for index, current_line in taf.iterrows():
# minimum_flight_category
taf.loc[index, 'Category'] = criteria.loc[
(current_line['Visibility'] >= criteria['visibility']) &
(lowest_bkn_or_ovc_height(current_line) >= criteria['ceiling'])
].index.max()
if index == 0:
taf.loc[index, 'ChangeGroup'] = 'BECMG'
continue
# -------------------------------------------------------
predominate_line = (
taf.loc[taf.loc[:, 'ChangeGroup'] == 'BECMG']).iloc[-1, ]
predom_max_speed = max_wind(predominate_line)
current_max_speed = max_wind(current_line)
becoming_conditions = [
((np.abs(predom_max_speed - current_max_speed) >= 10) |
# NOTE Wind Direction: A change > 30 degrees when the predominant
# wind speed or gusts are expected to be 15 knots or greater
((np.max([predom_max_speed, current_max_speed]) > 15) & (
np.abs(predominate_line['WindDirection'] -
current_line['WindDirection']) > 30))) |
# if the flight category has crossed a threshold
(taf.loc[index, 'Category'] != predominate_line['Category'])
]
taf.loc[index, 'ChangeGroup'] = (
np.where(becoming_conditions, 'BECMG', None))
return taf
if __name__ == '__main__':
dev_mock(pd.DataFrame.from_records(MOCK_DATA))
MOCK_DATA
is cat E. I'm working from a couple different environments. The output of the update is from a different data source which I'll post as well. \$\endgroup\$ChangeGroup
columns in the input always start off asNone
? \$\endgroup\$TEMPO
that I have yet to really start working on. ATEMPO
condition is a condition which would only be expected to only occur for an intermittent amount of time and potentially several other factors. After this function, rows withChangeGroup == None
get dropped. Valuesdf.fillna("")
df.astype(str)
formatted to the terminal aerodrome forecast specification. Then the entire dataframe is joined as a single stringrow\nrow\n...
. \$\endgroup\$