Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get "edge numbers" from list

Tags:

python

I have a list of data such as below:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 747, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799]

I'm trying to find the two consecutive numbers with the greatest distance between them out of this list.

In this case, the answer would be [47, 747] because they are listed right next to each other in the list and 747 - 47 = 700 which is a greater difference than any other pair of consecutive numbers

like image 403
Yuchen Huang Avatar asked Aug 15 '18 22:08

Yuchen Huang


4 Answers

>>> n = max(range(1, len(L)), key=lambda i: L[i] - L[i-1])
>>> L[n-1:n+1]
[47, 747]

A numpy based approach would be:

>>> a = np.array(L)
>>> n = np.diff(a).argmax()
>>> a[n:n+2]
array([ 47, 747])
like image 104
wim Avatar answered Oct 17 '22 01:10

wim


Here is a solution using max and zip

>>> l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 747, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799]
>>> max(zip(l,l[1:]), key=lambda t: abs(t[0]-t[1]))
(47, 747)
like image 41
Sunitha Avatar answered Oct 17 '22 00:10

Sunitha


You can use np.diff function:

import numpy as np
ls = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 747, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799]

indx = np.argmax(np.diff(ls))
print([ls[indx],ls[indx+1]])

Prints:

[47, 747]
like image 21
Paolo Avatar answered Oct 17 '22 01:10

Paolo


Assuming that your list is always monotonically increasing, and you just want to know the values:

for i in range(1, len(my_list)):
    if my_list[i] - my_list[i - 1] != 1:
        print(my_list[i - 1], my_list[i])

You can use a list comprehension to speed things up and retain a copy of the values:

pairs = [(my_list[i - 1], my_list[i]) for i in range(1, len(my_list)) if my_list[i] - my_list[i - 1] != 1]

If you want the pair with the max difference, apply max to the result:

max(pairs, key=lambda x: x[1] - x[0])

Numpy is generally a more elegant solution for dealing with numerical values. In particular, the diff function is useful for comparing neighbors:

my_array = np.array(my_list)
mask = np.diff(my_array)

Most numpy functions will convert numeric lists into arrays on input, and diff is no exception. The mask computed here is a boolean array that tells you the locations of edges. It is much easier to apply the mask if your data is in array format, so I did the transformation explicitly:

left = my_array[:-1][mask]
right = my_array[1:][mask]

Again, if you want the max, use np.argmax:

index = np.argmax(right - left)
print((left[index], right[index]))
like image 2
Mad Physicist Avatar answered Oct 17 '22 01:10

Mad Physicist