【问题标题】:Python: how to find elements in array x which have values close to elements in array y?Python:如何在数组 x 中查找值接近数组 y 中元素的元素?
【发布时间】:2016-08-18 12:27:50
【问题描述】:

数组 xy 中的元素是浮点数。我想在数组 x 中找到与数组 y 中的值尽可能接近的元素(对于数组 y 中的每个值- 数组 x 中的一个元素)。此外,数组 x 包含 >10^6 个元素和数组 y 大约 10^3,这是 for 循环 的一部分,所以它应该是最好快速完成。

我试图避免将它作为一个新的 for 循环,所以我这样做了,但是对于一个大 y 数组来说它非常慢

x = np.array([0, 0.2, 1, 2.4, 3,  5]); y = np.array([0, 1, 2]);
diff_xy = x.reshape(1,len(x)) - y.reshape(len(y),1);
diff_xy_abs = np.fabs(diff_xy);
args_x = np.argmin(diff_xy_abs, axis = 1);
x_new = x[args_x]

我是 Python 新手,欢迎提出任何建议!

【问题讨论】:

    标签: python arrays elements


    【解决方案1】:

    它是以 x 和 y 的顺序为代价的,但该代码是否满足您的性能需求? Rem:来自 x 的相同值可以用于多个 y 值。

    import numpy as np
    
    # x = np.array([0, 0.2, 1, 2.4, 3,  5]);
    # y = np.array([0, 1, 2]);
    x = np.random.rand(10**6)*5000000
    y = (np.random.rand(10**3)*5000000).astype(int)
    
    x_new = np.zeros(len(y))  # Create an 'empty' array for the result
    
    x.sort()  # could be skipped if already sorted
    y.sort()  # could be skipped if already sorted
    
    len_x = len(x)
    idx_x = 0
    cur_x = x[0]
    
    for idx_y, cur_y in enumerate(y):
        while True:
            if idx_x == len_x-1: 
                # If we are at the end of x, the last value is the best value
                x_new[idx_y] = cur_x
                break
            next_x = x[idx_x+1]
            if abs(cur_y - cur_x) < abs(cur_y - next_x):
                # If the current value of x is better than the next, keep it
                x_new[idx_y] = cur_x
                break
            # Check for the next value
            idx_x += 1
            cur_x = next_x
    
    print(x_new)
    

    【讨论】:

      【解决方案2】:

      可能对较大的数组进行排序,然后从其中二进制搜索较小数组的值,如果找到最接近的值并且附近的值在附近的索引中靠近它,如果没有找到,则最接近的值在旁边故障点。

      【讨论】:

      • 如果2个数组是排序好的,就不需要二分查找了。它可以在 O(n+m) 中求解,n 和 m 是 2 个数组的大小。查看我的代码。
      • 啊。我同意,所以这个想法是做一个合并排序类型的搜索,你推进 X 直到你得到当前 y 的最佳值,然后选择下一个 y ,所有好的值都在相同的位置或更远下 x。所以结果是 n+m 最大值。
      • 虽然对于非常大的 X,我的方法可能更快。因为它是关于 X 的对数
      • 我的应该在 O(m * log n) 左右
      【解决方案3】:

      下面给出了想要的结果。

      x[abs((np.tile(x, (len(y), 1)).T - y).T).argmin(axis=1)]
      

      tiles xy (len(y)) 中的每个元素,转置(.T) 这个平铺数组,减去y,重新转置它,采用absolute差异值,使用argmin(超过axis=1)确定最小值的索引,最后从x的这些索引中获取值。

      【讨论】:

      • @Bilja:太棒了!很高兴听到。顺便说一句,Upvoting 是向可能查看此问题的其他用户展示什么有用的好方法。 :)
      • :) 还不能投票,我的声望太低了(这里是新手)
      • @Bilja:啊!欢迎来到 StackOverflow。 :)
      • @Bilja 为什么当我的速度至少快 1 个数量级时,你认为这个解决方案比我的更好?在我的机器上,2Cubed 解决方案在 38 秒内运行,在 3 秒内运行。
      • @2Cubed:是的,使用更小的集合,你的更快。但是使用 Bilja 设置大小(x 为 1e6,y 为 1e3),我得到 Bilja:54 秒,你的:内存错误(Python 3.5.2 64b 和 16 GB 内存),我的:4 秒。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 2020-05-13
      • 1970-01-01
      • 2021-02-11
      • 2012-09-26
      • 1970-01-01
      • 2017-04-11
      相关资源
      最近更新 更多