Home > Mobile >  Finding differences in arrays
Finding differences in arrays

Time:04-13

I have an array in python which consists of distances in meters (chainage) between electric poles. Here’s a sample

d=([0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997, 1102, 1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980, 2083, 2178])

I want to write a script to compute the difference (section length) at every 1000m or close to 1000m but not exceeding 1000m.

Here’s an example

  • Section1 = 997 - 0

  • Section2 = 1980 - 997

  • Section3 = 2178 - 1980

The result should be in array

Section = ([997, 983, 198])

I’m a beginner in python. I’m still learning. I have not attached any code because I do not have any idea on where to start.

CodePudding user response:

So this will be slightly long since you're a beginner I'll try to break down some of what I'm doing here instead of just pasting code. If you have any questions feel free to respond and ask, but anyways here we go! So it sounds like you want to start out by creating a list with all of the values you've measured. In python to create a list you just use [] (and you'd use () to create a tuple). So starting with your list we have...

d=[0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997, 1102,1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980, 2083, 2178]

Next up we are going to need to find the differences. For starters lets create a variable that will keep track of our last value used (what will be subtracting) which in this case will start out as zero. Next we will also create our second list where we will store the differences.

current = 0
section = []

Now is the trickiest part of looping through them. So in Python you can iterate through a list, but in order to check the item we're currently on and make sure it is the closest to 1000 without going over we need access to the next item too. So instead of directly iterating over the list, we're going to iterate through a set of numbers, and each of these numbers will be the address of an item on the list starting with the first.

for i in range(len(d) - 1):

this statement right here is saying we are starting by setting i to zero, and will go through the loop of code we type next until we reach the length of list d minus 1. So now to check if the current item is the closest to 1000 without going over.

for i in range(len(d) - 1):
    if ((d[i] % 1000) == 0) or ((d[i] % 1000) > (d[i   1] % 1000)):
        section.append(d[i] - current)
        current = d[i]

So now this section is saying that if d[i] mod 1000 equals zero (the item in d at address i is 1000) or if the current item being investigated mod 1000 is greater than the next (which would indicate the next is greater than a multiple of 1000) then we add an element to our list of differences equal to d[i] - current and then change current to be equal to d[i].

This will take care of most of the work and now we just need to finish up with one last line.

section.append(d[len(d) - 1] - current)

This line takes the last element and always adds the difference between that and our current value like you seem to have wanted. So in the end our whole code is...

d=[0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997, 1102,1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980, 2083, 2178]
current = 0
section = []
for i in range(len(d) - 1):
    if ((d[i] % 1000) == 0) or ((d[i] % 1000) > (d[i   1] % 1000)):
        section.append(d[i] - current)
        current = d[i]

section.append(d[len(d) - 1] - current)

Hopefully this helped you solve your problem and learn a few things. Have a great one!

CodePudding user response:

Even if you don't know how to solve the problem efficiently, try and write something, it can be just how to get the 1000m intervals, even a cumbersome script to find the closest values. This is the only way to learn how to code, you have to practice and when you get stuck go and ask. There is a limit for the amount of value you can get from reading someone else's code.

For the solution to your problem, I compute the intervals relevant for the specific list given. Then I create a list to store the closest values from your list to the intervals and compute the intervals using a for loop. I use a list comprehension to compute the relevant section differences.

    intervals = np.arange(min(d),max(d) 1000,1000)
    closest_values = [min(d)]
    for i in intervals:
        diff = abs((d-i)/i)
        closest_values.append(d[np.argmin(diff)])
    section = [closest_values[i 1] - closest_values[i] for i,_ in enumerate(closest_values[:-1]]

Using your input list, after converting it to a numpy array, gave me the result of:

[997, 983, 198]

CodePudding user response:

Since you ask for a numpy solution, let's do away with those for loops:

d=np.array([0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997, 1102, 1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980, 2083, 2178])

def func(d, k = 1000):
    insert = (np.arange(d.max() // k)   1) * k                   #intermediate points
    vals = np.r_[d[0], d[np.searchsorted(d, insert) - 1], d[-1]] #values below the intermediate points
    return np.diff(vals)                                         #difference between the intermediate points

func(d)
Out[]: array([997, 983, 198])

CodePudding user response:

Another option: This might be a good opportunity to take a look at groupby() from the standard library's itertools module.

Try

from itertools import groupby

d = [0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997, 1102, 1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980, 2083, 2178]

for key, group in groupby(d, key=lambda n: n // 1000):
    print(f"{key = }, {list(group) = }")

and you'll get

key = 0, list(group) = [0, 98, 198, 300, 400, 500, 600, 700, 800, 900, 997]
key = 1, list(group) = [1102, 1187, 1282, 1382, 1480, 1570, 1670, 1775, 1885, 1980]
key = 2, list(group) = [2083, 2178]

groupby chops d into blocks according to the results of the key-function, which is floor-division by 1000.

With that in mind you could try

result, last = [], 0
for _, group in groupby(d, key=lambda n: n // 1000):
    current = list(group)[-1]
    result.append(current - last)
    last = current

to get

[997, 983, 198]
  • Related