Checking if n elements in an array are increasing

370 Views Asked by At

I have written a code for SPC and I am attempting to highlight certain out of control runs. So I was wondering if there was a way to pull out n(in my case 7) amount of increasing elements in an array so I can index with with the color red when I go to plot them. This is what I attempted but I obviously get an indexing error.

import  numpy as np
import matplotlib.pyplot as plt

y = np.linspace(0,10,15) 
x = np.array([1,2,3,4,5,6,7,8,9,1,4,6,4,6,8])
col =[]
  
for i in range(len(x)):
    if x[i]<x[i+1] and x[i+1]<x[i+2] and x[i+2]<x[i+3] and x[i+3]<x[i+4] and x[i+4]<x[i+5] and x[i+5]<x[i+6] and x[i+6]<x[i+7]:
        col.append('red')  
    elif x[i]>x[i+1] and x[i+1]>x[i+2] and x[i+2]>x[i+3] and x[i+3]>x[i+4] and x[i+4]>x[i+5] and x[i+5]>x[i+6] and x[i+6]>x[i+7]:
        col.append('red')  
    else:
        col.append('blue') 
  
for i in range(len(x)):
      
    # plotting the corresponding x with y 
    # and respective color
    plt.scatter(y[i], x[i], c = col[i], s = 10,
                linewidth = 0)

Any help would be greatly appreciated!

2

There are 2 best solutions below

2
On

To determine if all integer elements of a list are ascending, you could do this:-

def ascending(arr):
    _rv = True
    for i in range(len(arr) - 1):
        if arr[i + 1] <= arr[i]:
            _rv = False
            break
    return _rv


a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 16]
a2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16]

print(ascending(a1))
print(ascending(a2))

If you want to limit the sequence of ascending values then you could just use nested loops. It may look inelegant but it's surprisingly efficient and much simpler than bringing dataframes into the mix:-

def ascending(arr, seq):
    for i in range(len(arr) - seq + 1):
        state = True
        for j in range(i, i + seq - 1):
            if arr[j] >= arr[j + 1]:
                state = False
                break
        if state:
            return True
    return False


a1 = [100, 99, 98, 6, 7, 8, 10, 11, 12, 13, 14, 13]
a2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]

print(ascending(a1, 7))
print(ascending(a2, 7))
1
On

As Andy said in his comment you get the index error because at i=8 you get to 15 which is the length of x.

Either you only loop over len(x)-7 and just repeat the last entry in col 7 times or you could do something like this:

import  numpy as np
import matplotlib.pyplot as plt

y = np.linspace(0,10,20)
x = np.array([1,2,3,4,5,6,1,2,3,1,0,-1,-2,-3,-4,-5,-6,4,5])
col =[]

diff = np.diff(x) # get diff to see if x inc + or dec - // len(x)-1
diff_sign = np.diff(np.sign(diff)) # get difference of the signs to get either 1 (true) or 0 (false) // len(x)-2
zero_crossings = np.where(diff_sign)[0] + 2 # get indices (-2 from len(x)-2) where a zero crossing occures
diff_zero_crossings = np.diff(np.concatenate([[0],zero_crossings,[len(x)]])) # get how long the periods are till next zero crossing

for i in diff_zero_crossings:
    if i >= 6:
        for _ in range(i):
            col.append("r")
    else:
        for _ in range(i):
            col.append("b")

for i in range(len(x)):

    # plotting the corresponding x with y
    # and respective color
    plt.scatter(y[i], x[i], c = col[i], s = 10,
            linewidth = 0)

plt.show()