How to count the occurrence of consecutive hours that occur in dictionary

Viewed 91

I'm fairly new to Python and I'm trying to calculate the potential of Powdery Mildew occurring in agriculture crops using weather data.

1.The first indicator of Powdery Mildew is calculating the number of days in a date range where the temperature is between 70F and 85F.

I was able to build a dictionary from weather.json that only has the values from 70F and 85F but now I need to figure out the second part of the powdery mildew calculation

import json
import operator
import time
import datetime

min_hourly_temperature = 70
max_hourly_temperature = 85
hours_in_range = {}


for temperature, value in hourly_temperature_hora.items():
    if min_hourly_temperature <= temperature <= max_hourly_temperature:
        hours_in_range[temperature] = value

sorted_temp_in_range = sorted(hours_in_range.items(), key=operator.itemgetter(1))

date_hour_temp = dict(sorted_temp_in_range)

Here is the sorted dictionary of temperatures and the dates and hours where the temperature occurred.

date_hour_temp = {84.5: '2021-06-02 22:00:00', 72.9: '2021-06-05 01:00:00', 76.9: '2021-06-08 15:00:00', 80.4: '2021-06-09 18:00:00', 71.7: '2021-06-12 10:00:00', 82.8: '2021-06-12 17:00:00', 79.9: '2021-06-13 22:00:00', 75.9: '2021-06-14 02:00:00', 73.5: '2021-06-15 10:00:00', 75.4: '2021-06-15 11:00:00', 82.7: '2021-06-16 19:00:00', 76.5: '2021-06-17 11:00:00', 76.7: '2021-06-18 10:00:00', 76.2: '2021-06-19 01:00:00', 77.3: '2021-06-19 03:00:00', 74.8: '2021-06-19 04:00:00', 81.1: '2021-06-19 09:00:00', 82.4: '2021-06-19 23:00:00', 84.9: '2021-06-22 02:00:00', 76.8: '2021-06-22 08:00:00', 80.5: '2021-06-23 12:00:00', 75.2: '2021-06-25 03:00:00', 77.9: '2021-06-25 08:00:00', 71.2: '2021-06-27 03:00:00', 79.0: '2021-06-27 09:00:00', 79.6: '2021-06-30 02:00:00', 75.7: '2021-06-30 06:00:00', 82.6: '2021-06-30 08:00:00', 77.8: '2021-07-01 02:00:00', 78.1: '2021-07-01 04:00:00', 72.6: '2021-07-01 05:00:00', 83.3: '2021-07-01 10:00:00', 81.2: '2021-07-02 01:00:00', 77.5: '2021-07-02 02:00:00', 75.0: '2021-07-02 03:00:00', 70.9: '2021-07-02 04:00:00', 83.0: '2021-07-02 10:00:00', 72.4: '2021-07-03 07:00:00', 84.6: '2021-07-03 10:00:00', 73.0: '2021-07-04 06:00:00', 71.9: '2021-07-04 07:00:00', 84.1: '2021-07-05 02:00:00', 72.1: '2021-07-05 05:00:00', 70.0: '2021-07-05 07:00:00', 72.0: '2021-07-05 08:00:00', 77.1: '2021-07-05 09:00:00', 77.6: '2021-07-06 02:00:00', 71.3: '2021-07-06 06:00:00', 75.6: '2021-07-07 04:00:00', 83.6: '2021-07-07 23:00:00', 81.7: '2021-07-08 00:00:00', 79.1: '2021-07-08 02:00:00', 76.3: '2021-07-08 03:00:00', 74.1: '2021-07-08 04:00:00', 74.6: '2021-07-08 07:00:00', 80.7: '2021-07-08 22:00:00', 82.2: '2021-07-09 00:00:00', 81.0: '2021-07-09 01:00:00', 78.5: '2021-07-09 02:00:00', 74.0: '2021-07-09 06:00:00', 71.4: '2021-07-09 08:00:00', 74.9: '2021-07-09 09:00:00', 70.3: '2021-07-10 09:00:00', 75.5: '2021-07-10 10:00:00', 83.7: '2021-07-11 01:00:00', 84.8: '2021-07-11 02:00:00', 79.3: '2021-07-11 06:00:00', 82.0: '2021-07-11 09:00:00', 84.7: '2021-07-12 00:00:00', 78.4: '2021-07-12 02:00:00', 71.8: '2021-07-12 04:00:00', 74.2: '2021-07-12 05:00:00', 74.4: '2021-07-12 06:00:00', 76.1: '2021-07-12 09:00:00', 82.5: '2021-07-12 10:00:00', 84.0: '2021-07-13 02:00:00', 79.5: '2021-07-13 06:00:00', 78.8: '2021-07-13 07:00:00', 81.4: '2021-07-13 09:00:00', 83.4: '2021-07-13 10:00:00', 78.0: '2021-07-14 00:00:00', 73.4: '2021-07-14 03:00:00', 78.6: '2021-07-14 10:00:00', 83.9: '2021-07-14 11:00:00', 82.1: '2021-07-14 22:00:00', 78.9: '2021-07-14 23:00:00', 73.8: '2021-07-15 00:00:00', 72.5: '2021-07-15 03:00:00', 70.1: '2021-07-15 07:00:00', 80.8: '2021-07-15 10:00:00', 83.5: '2021-07-16 00:00:00', 79.2: '2021-07-16 03:00:00', 77.0: '2021-07-16 04:00:00', 75.8: '2021-07-16 05:00:00', 76.6: '2021-07-16 09:00:00', 81.8: '2021-07-16 10:00:00', 82.3: '2021-07-16 22:00:00', 81.3: '2021-07-17 00:00:00', 77.4: '2021-07-17 02:00:00', 75.1: '2021-07-17 03:00:00', 74.3: '2021-07-17 04:00:00', 70.4: '2021-07-17 06:00:00', 70.2: '2021-07-17 07:00:00', 72.3: '2021-07-17 08:00:00', 74.5: '2021-07-17 09:00:00', 79.4: '2021-07-17 10:00:00', 81.6: '2021-07-17 11:00:00', 80.3: '2021-07-17 22:00:00', 78.2: '2021-07-17 23:00:00', 71.1: '2021-07-18 00:00:00', 70.5: '2021-07-18 01:00:00', 70.6: '2021-07-18 02:00:00', 70.7: '2021-07-18 03:00:00', 73.1: '2021-07-18 05:00:00', 72.2: '2021-07-18 06:00:00', 73.3: '2021-07-18 09:00:00', 80.1: '2021-07-18 10:00:00', 84.3: '2021-07-18 11:00:00', 83.2: '2021-07-18 22:00:00', 79.7: '2021-07-18 23:00:00', 73.7: '2021-07-19 01:00:00', 80.9: '2021-07-19 02:00:00', 75.3: '2021-07-19 03:00:00', 73.9: '2021-07-19 04:00:00', 72.8: '2021-07-19 05:00:00', 72.7: '2021-07-19 06:00:00', 71.6: '2021-07-19 07:00:00', 74.7: '2021-07-19 08:00:00', 83.8: '2021-07-19 22:00:00', 79.8: '2021-07-20 00:00:00', 78.7: '2021-07-20 01:00:00', 76.4: '2021-07-20 02:00:00', 77.7: '2021-07-20 03:00:00', 73.6: '2021-07-20 05:00:00', 70.8: '2021-07-20 06:00:00', 71.0: '2021-07-20 08:00:00', 73.2: '2021-07-20 09:00:00', 77.2: '2021-07-20 10:00:00', 80.2: '2021-07-20 11:00:00', 82.9: '2021-07-20 12:00:00', 85.0: '2021-07-20 21:00:00', 81.9: '2021-07-20 22:00:00', 80.0: '2021-07-20 23:00:00'}

This is the part that is giving me trouble.

  1. The second part of the calculation is to count how many times this temperature occurs in six consecutive hours.

For each of these six consecutive hours in a day, the model assigns 20 points to the powdery_mildew_calculator.

So I'm trying to loop over my dictionary and count the occurrence of 6 consecutive hours in a day. If it doesn't occur in the dictionary print("No occurrence of 6 consecutive hours in the dictionary")

# Define Powdery Mildew Calculator
powdery_mildew_calculator = 0
powdery_mildew_positive = 20
powdery_mildew_negative = -10
powdery_mildew_calculator_max = 100
powdery_mildew_calculator_min = 0

get_start_date = list(date_hour_temp.values())[0]
get_end_date = list(date_hour_temp.values())[-1]

date_format = '%Y-%m-%d %H:%M:%S'
start = datetime.datetime.strptime(get_start_date, date_format)
end = datetime.datetime.strptime(get_end_date, date_format)

pm_hourly_calculator = 0
while start <= end:
    for i in date_hour_temp.values():
       if #THIS IS WHERE I'M STUCK IF HOURS CONSECUTIVE THEN pm_hourly_calculator +=1

I have been reading over the DateTime python documentation https://docs.python.org/3/library/datetime.html and have attempted a few loops but I'm not getting the results I'd like.

What I would like from the output is for each occurrence of six hours consecutive hours in a day the calculator gives 20 points.

2 Answers

You can use defaultdict to group the datetime by date then use datetime range to find consecutive hours

from collections import defaultdict
from datetime import datetime, timedelta

data = defaultdict(list)
for date in date_hour_temp.values():
  data[date.split()[0]].append(date)

for date_lst in data.values():
  if len(date_lst) > 5:
    for date in date_lst:
      start_date = datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
      date_set = set((start_date + timedelta(hours=i)).strftime('%Y-%m-%d %H:%M:%S') for i in range(1, 7))
      if len(date_set.intersection(date_lst)) >= 6:
        print(date_lst)
        # do something
        break

Output:

['2021-07-19 01:00:00', '2021-07-19 02:00:00', '2021-07-19 03:00:00', '2021-07-19 04:00:00', '2021-07-19 05:00:00', '2021-07-19 06:00:00', '2021-07-19 07:00:00', '2021-07-19 08:00:00', '2021-07-19 22:00:00']

A list of tuples instead of a dict seems better; example below:

Mac_3.2.57$cat powder.py
import json
import operator
import time
import datetime

min_hourly_temperature = 70
max_hourly_temperature = 85
hours_in_range_sorted = []
hourly_temperature_hora = [
(77.2, '2021-07-20 10:00:00'), (80.2, '2021-07-20 11:00:00'), (92.2, '2021-07-20 12:00:00'), (85.0, '2021-07-20 21:00:00'), (81.9, '2021-07-20 22:00:00'), (69.9, '2021-07-20 23:00:00')]

print "before:"
print hourly_temperature_hora
for temperature, value in hourly_temperature_hora:
    if min_hourly_temperature <= temperature <= max_hourly_temperature:
        hours_in_range_sorted.append((temperature, value))
hours_in_range_sorted.sort(key=lambda x: x[0])
print "after:"
print hours_in_range_sorted
Mac_3.2.57$python powder.py
before:
[(77.2, '2021-07-20 10:00:00'), (80.2, '2021-07-20 11:00:00'), (92.2, '2021-07-20 12:00:00'), (85.0, '2021-07-20 21:00:00'), (81.9, '2021-07-20 22:00:00'), (69.9, '2021-07-20 23:00:00')]
after:
[(77.2, '2021-07-20 10:00:00'), (80.2, '2021-07-20 11:00:00'), (81.9, '2021-07-20 22:00:00'), (85.0, '2021-07-20 21:00:00')]
Mac_3.2.57$
Related