Reputation: 939
I have an array of integers derived from a gradient of a line. The array is called sign_slope and looks like this:
sign_slope = array([-1, 1, -1, ..., -1, -1, -1])
I am searching for the cases whereby consecutive items within the array are: 1, -1 For example you can see from the above output of sign_slope that: sign_slope[1] = 1 and sign_slope[2] = -1 This would be the first case of many that I would like to detect item/index numbers for. I would like the code to output an array or list of index numbers corresponding to the (n-1)'th index i.e. sign_slope[1] in the above case. I have written the below printing statement which appears to work. However, I do not know how to output the index numbers rather than the values as currently is the case and append them to a list or input them into an array.
for n in range(0, len(sign_slope)):
if sign_slope[n] < 0 and sign_slope[n - 1] > 0:
print sign_slope[n - 1]
else:
print 0
Thanks is advance,
Kane
Upvotes: 1
Views: 9139
Reputation: 2526
You can do this without writing a loop, assuming your array sign_slope
is a numpy
array:
import numpy as np
# some data
sign_slope = np.array([-1, 1, -1, 1, 1, -1, -1])
# compute the differences in s
d = np.diff(sign_slope)
# compute the indices of elements in d that are nonzero
pos = np.where(d != 0)[0]
# elements pos[i] and pos[i]+1 are the indices
# of s that differ:
print s[pos[i]], s[pos[i]+1]
Here's an ipython session showing the values of the variables:
In [1]: import numpy as np
In [2]: s = np.array([-1, 1, -1, 1, 1, -1, -1])
In [3]: d = np.diff(s)
In [4]: print d
[ 2 -2 2 0 -2 0]
In [5]: pos = np.where(d != 0)[0]
In [6]: print pos
[0 1 2 4]
In [7]: print s[pos[0]], s[pos[0]+1]
-1 1
In [8]: print s[pos[1]], s[pos[1]+1]
1 -1
In [9]: print s[pos[2]], s[pos[2]+1]
-1 1
In [10]: print s[pos[3]], s[pos[3]+1]
1 -1
Hope this helps
Edit: Actually, in retrospect, I'm missing some of the differences. I'll get back to you on that. Sorry for any confusion.
Edit 2: Fixed, I made a silly error.
Upvotes: 0
Reputation: 88977
Looping over a range of indicies is generally considered very unpythonic. It reads very poorly and masks what you are really trying to do. As such, a better solution to finding your sublist is to loop through using the enumerate()
builtin to get the indicies alongside the values. We can also provide a much more generic solution, and make it a generator which makes it easy to use.
def find_sublists(seq, sublist):
length = len(sublist)
for index, value in enumerate(seq):
if value == sublist[0] and seq[index:index+length] == sublist:
yield index
What we do here is loop through the list, taking the indicies where the value matches the beginning of our sublist. We then check to see if that segment of the list matches our sublist, if it does, we yield
the index. This allows us to quickly find all matching sublists in a list.
We can then use this like so, using the list
builtin to create a list from the generator:
>>> list(find_sublists([-1, 1, -1, -1, -1, 1, -1], [1, -1]))
[1, 5]
Upvotes: 4