1

I have code which is supposed to find out extremums in a generated NumPy array and write them down in a new array one by one (min, max, min, max, etc.) This code works, but it is too slow. So I need to do it without cycles. I've removed one with numpy.logical_and, but those two left are big ones. Maybe np.where will work, but I don't know how to use them here.

Code

import numpy as np
from scipy.signal import argrelextrema
import matplotlib.pyplot as plt
import timeit


if __name__ == '__main__':
    N = 1000000  # Length of an array
    T = 4  # Diff between indexes of an array
    D = 4  # Diff between values of an array
    x = np.random.uniform(low=-1, high=1, size=N)
    x[0] = 1  # Starting value
    x = np.cumsum(x)  # Using cumsum for faster generating
    index = []  # Array for indexes of local extremums
    mins = argrelextrema(x, np.less)[0]  # Array of min local extremums
    maxs = argrelextrema(x, np.greater)[0]  # Array of max local extremums
    # print('AutoGenerated NumPy massive prepared using np.cumsum() \n', x)
    index.append(mins[0])  # Zero will be min
    min_elem = mins[0]
    assert index[0] in mins
    for max_elem in maxs:
        # Checking the diff in values and in indexes, write if if suites
        if x[max_elem] - x[min_elem] >= D and max_elem - min_elem >= T:
            # Check if there's more suitable local minimum
            min_elem = np.argmin(x[min_elem:max_elem]) + min_elem
            index[-1] = min_elem
            index.append(max_elem)
            assert index[-1] in maxs
            assert max_elem - min_elem >= T
            assert x[max_elem] - x[min_elem] >= D
            assert np.all(np.logical_and(x[min_elem+1:max_elem] >= x[min_elem],
                                         x[min_elem+1:max_elem] <= x[max_elem]))
            for min_elem in mins:
                # Checking the diff in values and in indexes, write if if suites
                if x[max_elem] - x[min_elem] >= D and min_elem - max_elem >= T:
                    # Check if there's more suitable local maximum
                    max_elem = np.argmax(x[max_elem:min_elem]) + max_elem
                    index[-1] = max_elem
                    index.append(min_elem)
                    assert index[-1] in mins
                    assert min_elem - max_elem >= T
                    assert x[max_elem] - x[min_elem] >= D
                    break
Community
  • 1
  • 1
vlad ustimov
  • 91
  • 1
  • 6

1 Answers1

0

Suggestions:

Edits:

  • Remove all unneeded "print" statements before testing code, as Console Output is slow and will give you incorrect timing.

  • Added error message to the assert statements such as assert x >= 0, 'x is less than zero'

  • Try to eliminate x in y statements as the language/compiler must check every element in y to see if x exists. References

Good Luck.

Dean Van Greunen
  • 5,060
  • 2
  • 14
  • 28