【问题标题】:Minimum distance for each value in array respect to other数组中每个值相对于其他值的最小距离
【发布时间】:2019-05-07 14:15:24
【问题描述】:

我有两个整数 A 和 B 的 numpy 数组。数组 A 和 B 中的值对应于事件 A 和 B 发生的时间点。我想转换 A 以包含自最近事件 b 发生以来的时间。

我知道我需要将 A 的每个元素减去最接近 B 的元素,但我不确定该怎么做。任何帮助将不胜感激。

>>> import numpy as np

>>> A = np.array([11, 12, 13, 17, 20, 22, 33, 34])
>>> B = np.array([5, 10, 15, 20, 25, 30])

期望的结果:

cond_a = relative_timestamp(to_transform=A, reference=B)
cond_a
>>> array([1, 2, 3, 2, 0, 2, 3, 4])

【问题讨论】:

  • 嗨,如果我不清楚,对不起。目标是计算每个事件 A 和 B 中小于该事件的事件之间的最小距离。
  • 嘿拉斐尔。实际上,A 和 B 包含数十万个条目。我还向 B 引用了许多不同的数组。我不太了解计算时间,但我认为 for 循环可能太慢了。
  • 你可以使用np.searchsorted:idx=np.searchsorted(B,A, side='right'); result=A-B[idx-1]
  • @Brenlla 有什么理由不将此作为答案发布?
  • @RafaelC 没有特别的原因,但我觉得这一定是以前问过的。经过搜索,我找到了几个答案herehere

标签: python numpy data-science


【解决方案1】:

您可以使用np.searchsorted 查找应在B 中插入A 元素以保持顺序的索引。换句话说,您正在为A 中的每个元素在B 中找到最接近的元素:

idx = np.searchsorted(B, A, side='right')
result = A-B[idx-1] # substract one for proper index

根据docs searchsorted 使用binary search,因此它可以很好地适应大型输入。

【讨论】:

    【解决方案2】:

    这是一种计算成对差异的方法。请注意,它具有O(n**2) 复杂性,因此对于较大的数组,@brenlla 的答案可能会表现得更好。

    这里的想法是使用np.subtract.outer,然后在masked array 上找到沿轴1 的最小差异,其中仅考虑B 中小于a 的值:

    dif = np.abs(np.subtract.outer(A,B))
    np.ma.array(dif, mask = A[:,None] < B).min(1).data
    # array([1, 2, 3, 2, 0, 2, 3, 4])
    

    【讨论】:

    • 这很好用,但是outer 操作的时间(和内存)复杂度是 O(n**2),所以这只对小输入有用
    • 是的,同意...你用np.searchsorted 回答要好得多,没想过在这里使用它。我建议您将其发布为答案,我将删除我的答案或添加有关复杂性的注释警告@brenlla
    【解决方案3】:

    我不确定,如果计算所有成对差异真的更快,而不是在每个数组条目上使用 python 循环(最坏情况 O(Len(A)+len(B)),使用循环的解决方案:

    A = np.array([11, 12, 13, 17, 20, 22, 33, 34])
    B = np.array([5, 10, 15, 20, 25, 30])
    
    def calculate_next_distance(to_transform, reference):
        max_reference = len(reference) - 1
        current_reference = 0
        transformed_values = np.zeros_like(to_transform)
        for i, value in enumerate(to_transform):
            while current_reference < max_reference and reference[current_reference+1] <= value:
                current_reference += 1
            transformed_values[i] = value - reference[current_reference]
        return transformed_values
    
    calculate_next_distance(A,B)
    # array([1, 2, 3, 2, 0, 2, 3, 4])
    

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 2020-12-29
      • 2020-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多