Danny
Danny

Reputation: 505

How do I fill in missing numbers in a predictable stepped list?

I have a list of the 3–5 high and low tide events throughout a 24 hour period, placed at the appropriate index based on their timestamp:

tides = [None, None, None, (0.07, 'low'), None, None, None, None, None, None, (2.14, 'high'), None, None, None, None, None, (0.32, 'low'), None, None, None, None, None, (1.34, 'high'), None]

For instance: that (0.07, 'low') value is at index 3 because it occurs at around 3am.

I'd like to replace the None values with stepped values between known values.

I know how to do this manually:

difference = tides[10][0] - tides[3][0] # 2.07
steps = 10 - 3 # 7
increment = difference / steps # 0.2957142857

# Add to each list item
tides[4] = (tides[3][0] + (increment * 1), '')
tides[5] = (tides[3][0] + (increment * 2), '')
tides[6] = (tides[3][0] + (increment * 3), '')
# etc...

...but how would I approach this programmatically?

This approach should:

  1. Take into account the 'direction' (up or down) of the wave and make a negative or positive step value accordingly
  2. Handle a changing number of and time of each tide event each day (therefore varying amounts and indexes of known list items)
  3. Fill in the unknown first and last values by 'reflecting' the adjacent known stepped value (to complete the curve)

Failed attempts

My attempts revolve around looping through the above list and trying to define the steps:

for i in range(24):
   if tides[i] != None:
      # Known value
   else:
      # Missing value
      # Get 'out' and calculate steps from known neighbours

I get stuck at that last part: understanding how to be 'within' an index in a loop whilst also finding its nearest known neighbours and calculating steps.

I have also tried making a separate 'known' list (which includes the indexes) to compare against, that looks like this:

tidesKnown = [(3, 0.07, 'low'), (10, 2.14, 'high'), (16, 0.32, 'low'), (22, 1.34, 'high')]

Upvotes: 0

Views: 41

Answers (1)

Павел
Павел

Reputation: 121

for i in range(len(tidesKnown) - 1):
    start_tide = tidesKnown[i]
    end_tide = tidesKnown[i+1]
    difference = end_tide[1] - start_tide[1]
    step = end_tide[0] - start_tide[0]
    increment = difference / step

    for k in range(start_tide[0] + 1, end_tide[0]):
        elem = (tides[k-1][0] + increment, tides[k-1][1])
        tides[k] = elem

Here we simply iterate over the known values, and for each pair we fill in the value as the previous + increment.

The result for your dataset is:

[None, None, None, (0.07, 'low'), (0.36571428571428577, 'low'), (0.6614285714285715, 'low'), (0.9571428571428573, 'low'), (1.2528571428571431, 'low'), (1.548571428571429, 'low'), (1.8442857142857148, 'low'), (2.14, 'high'), (1.836666666666667, 'high'), (1.5333333333333337, 'high'), (1.2300000000000004, 'high'), (0.9266666666666671, 'high'), (0.6233333333333337, 'high'), (0.32, 'low'), (0.49, 'low'), (0.66, 'low'), (0.8300000000000001, 'low'), (1.0, 'low'), (1.17, 'low'), (1.34, 'high'), None]

If you need to remove None also at the beginning of the list based on its end, you need to write a separate code for this.

Upvotes: 1

Related Questions