【问题标题】:Finding the point of intersection of 3 Numpy Arrays Python找到 3 个 Numpy 数组 Python 的交点
【发布时间】:2021-05-01 16:07:23
【问题描述】:

我正在尝试编写一个函数,它为我提供list_2list_3crosses list_ 的索引。因此,如果 numpy 代码中有任何交点,它会给我交点。我想按顺序获得十字架,因此必须对索引列表进行格式化,以便按照list_2 cross, list_3 cross , list_2 crosslist_3 cross, list_2 cross , list_3 cross 等的顺序给我一个十字架。所以如果发生十字架,它必须等待其他数组值要穿过list,然后才能通过。尽管我尝试过使用numpy.where()function 等,但我不知道如何解决这个问题,我也在使用 pandas 模块,所以如果它有一个有效的函数,我也可以使用它。

变量:

list_ = np.array([9887.89 9902.99 9902.99 9910.23 9920.79 9911.34 9920.01 9927.51 9932.3
 9932.33 9928.87 9929.22 9929.22 9935.24 9935.24 9935.26 9935.26 9935.68
 9935.68 9940.5 ])
list_2 = np.array([9935.26 9935.26 9935.68 9935.68 9940.5  9925.19 9925.19 9929.62 9929.65
 9929.93 9932.55 9936.81 9936.84 9937.26 9932.55 9932.55 9932.55 9932.6
 9932.6  9932.6])
list_3_ = np.array([9928.87 9929.22 9929.22 9935.24 9935.24 9935.26 9935.26 9935.68 9935.68
 9940.5  9925.19 9925.19 9929.62 9929.65 9929.93 9932.55 9936.81 9936.84
 9937.26 9932.55])

情节:

预期输出:

List_2 cross at 5, List_3 cross at 10, List_2 cross at 14, List_3 cross at 15, List_2 cross at 18, List_3 cross at 19

【问题讨论】:

  • 这就是你要找的(return_indices=True)吗? numpy.org/doc/stable/reference/generated/numpy.intersect1d.html
  • 列表的长度是否相同?
  • 您能否通过显示示例数据的返回值来说明您的意思
  • 是的,它们的大小相同,我将通过提供图形值来更新它
  • @Stuart 希望解释更好,现在我已经更新了。我想我可以使用intersect1d() 函数,但我真的不知道如何格式化它。

标签: python list function numpy intersection


【解决方案1】:

两个系列ab 之间的交叉点或交叉点索引是索引i 其中:

  • 要么 (aii 和 ai+1 > bi+1) ( b 从上方穿过 a
  • 或 (ai > bi and ai+1i+1) ( b 从下方穿过 a
  • 或ai = biab touch)

所以我们可以通过比较每个数组的“当前”(i-th)和“下一个”(i+1-th)值来获得索引。

def intersection_points(a, *others):
    if a.ndim != 1 or any(other.shape != a.shape for other in others):
        raise ValueError('The arrays must be single dimensional and the same length')
    others = np.array(others)
    indices = np.argwhere(
            ((a[:-1] < others[..., :-1]) & (a[1:] > others[..., 1:])) |  
            ((a[:-1] > others[..., :-1]) & (a[1:] < others[..., 1:])) | 
            (a[:-1] == others[..., :-1]))
    return indices[indices[:, 1].argsort()]   # sort by i

a = np.array([9887.89, 9902.99, 9902.99, 9910.23, 9920.79, 9911.34, 9920.01, 9927.51, 9932.3, 9932.33, 9928.87, 9929.22, 9929.22, 9935.24, 9935.24, 9935.26, 9935.26, 9935.68, 9935.68, 9940.5])
b = np.array([9935.26, 9935.26, 9935.68, 9935.68, 9940.5, 9925.19, 9925.19, 9929.62, 9929.65, 9929.93, 9932.55, 9936.81, 9936.84, 9937.26, 9932.55, 9932.55, 9932.55, 9932.6, 9932.6, 9932.6])
c = np.array([9928.87, 9929.22, 9929.22, 9935.24, 9935.24, 9935.26, 9935.26, 9935.68, 9935.68, 9940.5, 9925.19, 9925.19, 9929.62, 9929.65, 9929.93, 9932.55, 9936.81, 9936.84, 9937.26, 9932.55])
print(intersection_points(a, b, c))

这会以这种格式返回一个交点数组:

[[ 0  7]
 [ 0  9]
 [ 1  9]
 [ 1 11]
 [ 1 12]
 [ 0 13]
 [ 1 15]
 [ 1 18]]

意味着b(您的list_2)在索引7、9、13处与a相交,而c(您的list_3)在索引9、11、12处与a相交, 15 和 18。

您似乎希望返回的值以某种方式在不同线的交点之间交替,并“等待其他数组值穿过列表才能通过”。尚不完全清楚这在每种情况下意味着什么,但您可以通过像这样操作结果来做到这一点:

ip = intersection_points(a, b, c)
print(np.concatenate(([ip[0]], ip[1:][ip[:-1, 0] != ip[1:, 0]])))

返回

[[ 0,  7],
 [ 1,  9],
 [ 0, 13],
 [ 1, 15]]

即第一个交叉点是索引 7 处的 b,然后是索引 9 处的 c,然后是 13 处的 b,最后是 15 处的 c

【讨论】:

  • 我试图将这个实现到一个长度为 270 万个数组的大型数据集。它给了我一个价值错误。 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
  • 还有一个问题*others在程序中做了什么,除了主列表之外,它还吸收了额外的lists吗?
  • 你的阵列是什么形状的?如果它们是一维的,例如示例中的 a、b 和 c,那么它们的长度应该无关紧要。
  • Yes *others 允许您在函数中指定任意数量的额外数组作为参数
  • 是的,它们都是一维的,b 和 c 的长度为 2666447,每个错误消息是 ValueError: operands could not be broadcast together with shapes (2669446,) (2,2666446) 我将就此提出一个新问题。 `
【解决方案2】:

此函数将数组转换为列表并返回元组列表:

def find_cross(list_, list_2, list_3):
    
    list_ = list_.tolist()
    list_2 = list_2.tolist()
    list_3 = list_3.tolist()
    
    cross = []
    i=0
    for x,y in zip(list_2, list_3):
        if x in list_:
            cross.append((i, list_.index(x)))
        if y in list_:
            cross.append((i, list_.index(y)))
        i+=1
    return cross

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多