【问题标题】:Elementwise comparison between two arrays without for loops in NumpyNumpy中没有for循环的两个数组之间的元素比较
【发布时间】:2020-12-10 11:26:36
【问题描述】:

我有一个名为 dataset 的大数组,尺寸为 Numpy(700、28、28、3)。假设这个矩阵如下所示:

>>> dataset=np.random.rand(5600,28,28,3)
>>> dataset.shape
(5600, 28, 28, 3)

现在,假设我有另一个更简单的数组,称为 query,我将使用它在 dataset 数组中搜索

>>> query=np.random.rand(28,28,3)
>>> query.shape
(28, 28, 3)

在较大的矩阵查询中搜索该矩阵的一种方法是计算它与数组数据集的所有元素之间的均方误差。较小的 MSE 告诉我矩阵在数组 dataset 中的位置。

问题是,我不想在 Python 中创建一个 for 循环来逐个计算 MSE,将 MSE 存储在另一个数组中,然后在循环结束时获取最小 MSE 的位置。在此比较之前,我已经有两个 for 循环,因此,我希望使其尽可能高效和快速。没有大的for循环是否可以解决这样的问题?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    你可以这样做:

    se = (dataset-query)**2                            # Squared error - shape (L,28,28,3)
    sum_of_se = np.sum(se.reshape(-1,28*28*3), axis=1) # Sum of squared error - shape (L,)
    print (np.argmin(sum_of_se))                       # Position of minimum within sum_of_se
    

    【讨论】:

      【解决方案2】:

      您可以创建一个扫描仪函数,使用map 扫描数据集,然后从生成的地图中提取最小 MSE 位置:

      MSE_scanner = lambda A : ((query-A)**2).mean() # create the MSE comparison function
      MSE_array = list(map(MSE_scanner, dataset)) # array of MSEs relevant to query
      MSE_minimum = min(MSE_array) # extract the minimum MSE which should the one matched
      query_location = MSE_array.index(MSE_minimum) # extract the location of the minimum MSE
      

      【讨论】:

      • 我个人的看法,这比写得很好的 for 循环效率低,我认为 for 循环是最有效的算法方式,任何更高的效率都必须来自并行化而不是算法,但我可能是错的,很想听听其他想法
      • 您可能是对的,for 循环是最有效的。它可能比迄今为止发布的三个答案(包括我的)更快,因为在内部(在引擎盖下,所有这些答案都会在一个长序列中进行多次传递(遍历)。(至少一次遍历来计算 SE 或 MSE 或欧几里得距离。然后至少再通过一次以找到其中的最小值。)使用for 循环,在一次通过中,您可以计算 SE 或 MSE 或欧几里得距离,并继续注意“运行最小值” . 到那一关结束,就可以有最小的位置了。
      【解决方案3】:

      为此,您可以使用cdist,使用平方欧几里得距离:

      import numpy as np
      from scipy.spatial.distance import cdist
      
      dataset = np.random.rand(5600, 28, 28, 3)
      query = np.random.rand(28, 28, 3)
      
      res = cdist(query.reshape((1, -1)), dataset.reshape((5600, -1)), 'seuclidean')
      print(np.argmin(res))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-13
        • 1970-01-01
        • 2021-08-08
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-02-16
        相关资源
        最近更新 更多