2

I have a large file with wind speed and direction every second. I have stored each element into a numpy array. The wind speeds for example are ws=(7, 8, 8.5, 8, 9.5). I would like to fill another array with the maximum 1 minute wind speed, so every 60 instances, I need to pull the max. I have tried this:

gust = np.full(len(ws), 0) 
indices = sig.argrelmax(ws)
gust[indices] = ws[indices]

his arbitrarily pulls out maximums and enters them successfully into an array while maintaining the same index they had in the ws array, but 1) I need it to check for maximum in batches of 60 (1-60, 61-120,...etc). 2) It turns the number in an integer and I need floats to remain as floats.

Jonathon
  • 251
  • 1
  • 7
  • 20

2 Answers2

4

If the number of elements is a multiple of 60, you can reshape the array, and then calculate the maximum over the second dimension:

ws.reshape(-1, 60).max(axis=1)

If we for example use random data, we get:

>>> ws = np.random.randn(7*60)
>>> ws.reshape(-1, 60).max(axis=1)
array([2.81337727, 2.30824229, 2.31009178, 2.5588816 , 3.41887582,
       2.21686554, 2.10892784])

If the number of measurements is not a multiple of 60, you can "pad" it with zeros (since the wind speed is minimum 0):

# padding zeros at the end
ws2 = np.append(ws, (0,) * ((60-len(ws))%60))
ws2.reshape(-1, 60).max(axis=1)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • The particular file is in fact a multiple of 60 but would be nice to have that not be a requirement. I am plotting these values with time. The timestamps are in a second array.. So corresponding wind speed and the time it occurs will remain in the same index for plotting . Won't reshaping the wind like that mess it up? I need it to stay in the same index spot as it is in the original wind speed array. – Jonathon Apr 16 '20 at 16:48
  • 1
    @Jonathon: well as described you can perform padding of zeros as described at the bottom. Reshaping will not change the original numpy array, especially since reshaping is done on a *view* returned by the function, the original array remains unchanged. So we only construct a *view* and make calculations on that view, but the `ws` data remains the same. – Willem Van Onsem Apr 16 '20 at 16:50
2

If you want to handle non multiples of 60 in a more direct way you can use reduceat:

wind=np.random.normal(size=1000)
res=np.maximum.reduceat(wind, np.r_[:wind.size:60])

np.r_ creates an array of indices 0,60,120...

reduceat performs the ufunc maximum at the slices between consecutive indices

And so the last element of res is the max of the last 1000%60 elements of wind

Brenlla
  • 1,471
  • 1
  • 11
  • 23
  • I really like this method. How would I plug those maximum values back into an array the same size as the wind file so that I can plot the maximums along with the wind? I would like to be able to plot those maximums in the same index position as gust and wind speed will be on the same chart. – Jonathon Apr 16 '20 at 17:17
  • Not sure I follow, you could just change the `x` (using [np.linspace](https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html)) when plotting `res`: `plt.plot(wind); plt.plot(np.linspace(60/2, wind.size, res.size), res)` – Brenlla Apr 16 '20 at 17:26
  • So if the wind speed array is [3,4,5,4,2], and I pull the maximum as you instructed, I would like the wind maximum array to be [ 0,0,5,0,0 ]. Same size array, but only with the max values – Jonathon Apr 16 '20 at 18:20