查找数组中的差异

Finding differences in arrays

我在 python 中有一个数组,其中包含以米为单位的电线杆之间的距离(桩号)。这是一个示例

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

我想编写一个脚本来计算每 1000 米或接近 1000 米但不超过 1000 米的差异(路段长度)。

举个例子

结果应该在数组中

Section = ([997, 983, 198])

我是 python 的初学者。我还在学习。我没有附加任何代码,因为我不知道从哪里开始。

所以这会有点长,因为您是初学者,我将尝试分解我在这里所做的一些事情,而不仅仅是粘贴代码。如果您有任何问题,请随时回复和提问,但无论如何我们开始吧!所以听起来您想首先创建一个包含您测量的所有值的列表。在 python 中创建一个列表,您只需使用 [] (并且您将使用 () 创建一个元组)。因此,从您的列表开始,我们有...

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 = []

现在是遍历它们的最棘手的部分。因此,在 Python 中,您可以遍历列表,但为了检查我们当前使用的项目并确保它最接近 1000 而不会超过,我们也需要访问下一个项目。因此,我们不是直接遍历列表,而是遍历一组数字,这些数字中的每一个都是列表中从第一个开始的项目的地址。

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

这里的语句是说我们从将 i 设置为零开始,然后将执行我们接下来键入的代码循环,直到我们达到列表 d 减 1 的长度。所以现在检查当前项目是否最接近1000不超过

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]

所以现在这一节是说如果d[i] mod 1000等于0(地址i处的d中的项目是1000)或者如果当前正在调查的项目mod 1000是大于下一个(这表明下一个大于 1000 的倍数)然后我们将一个元素添加到我们的差异列表中等于 d[i] - current 然后将 current 更改为等于 d[i].

这将完成大部分工作,现在我们只需要完成最后一行。

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

这一行采用最后一个元素,并总是添加它与我们当前值之间的差异,就像您似乎想要的那样。所以最后我们的整个代码是...

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)

希望这能帮助您解决问题并学到一些东西。玩得开心!

即使你不知道如何有效地解决问题,试着写点东西,它可以只是如何获得 1000 米的间隔,甚至是寻找最接近值的繁琐脚本。这是学习如何编码的唯一方法,你必须练习,当你遇到困难时去问。阅读别人的代码所能获得的价值是有限度的。

为了解决您的问题,我计算了与给定的特定列表相关的区间。然后我创建一个列表来存储列表中最接近间隔的值,并使用 for 循环计算间隔。我使用列表理解来计算相关部分差异。

    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]]

使用您的输入列表,将其转换为 numpy 数组后,得到的结果为:

[997, 983, 198]

既然您要求 numpy 解决方案,那么让我们去掉那些 for 循环:

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])

另一种选择:这可能是查看 groupby() from the standard library's itertools 模块的好机会。

尝试

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) = }")

你会得到

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 根据 key 函数的结果将 d 分成块,即 floor-division by 1000.

考虑到这一点,您可以尝试

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

得到

[997, 983, 198]