【问题标题】:optimal agorithm to delete elements from numpy arrays从numpy数组中删除元素的最佳算法
【发布时间】:2020-08-12 23:53:14
【问题描述】:

您好,我想知道这个算法是否更有效。目的是当半径大于用户设置的最大半径时,删除3个数组中的所有点。

此代码在比率数组中搜索位置“i”,当该值大于 max_rad 时,它会从 Nx1 的 3 个 numpy 数组中删除元素“i”。

for i in range(len(rad_vec)-1,-1,-1):
    if rad_vec_temp[i] >= max_rad :
        azim_vec = np.delete(azim_vec, i)
        elev_vec = np.delete(elev_vec, i)
        rad_vec = np.delete(rad_vec, i)

我需要另一种方法来执行相同的过程,但比这种方法更快。

【问题讨论】:

  • 只需根据条件和索引创建掩码即可。不要迭代,使用矢量化方法

标签: python arrays algorithm numpy sorting


【解决方案1】:

与其删除代价高昂的,不如尝试如下选择:

#if rad_vec_temp is not an array, first convert it to an array
rad_vec_temp = np.array(rad_vec_temp)
mask = rad_vec_temp<max_rad
azim_vec = azim_vec[mask]
elev_vec = elev_vec[mask]
rad_vec = rad_vec[mask]

【讨论】:

    【解决方案2】:

    每次调用np.delete,数组都会被重新分配。这使操作变得昂贵。 Numpy 是关于批量操作的,所以这里有一些不同的方法供您进行基准测试。它们都取决于您可以为要删除的位置创建一个掩码数组这一事实:

    to_delete = (rad_vec_temp >= max_rad)
    

    或者,保留一个:

    to_keep = (rad_vec_temp < max_rad)
    
    1. 使用delete,但只用一次:

       azim = np.delete(azim, to_delete)
       elev = np.delete(elev, to_delete)
       rad = np.delete(rad, to_delete)
      

      请记住,每次传入掩码时,都必须对其进行两次遍历:一次计算被掩码元素的数量,另一次在分配输出后应用掩码。这不是有效的,因为它发生了 3 次。

    2. 为避免多次通过掩码,您可以将其转换为索引:

       indices = np.flatnonzero(to_delete)
       azim = np.delete(azim, indices)
       elev = np.delete(elev, indices)
       rad = np.delete(rad, indices)
      
    3. 您还可以使用带有反向掩码的直接索引来指示要保留的位置。这是更常见的方式,因为它的读写非常简单:

       azim = azim[to_keep]
       elev = elev[to_keep]
       rad = rad[to_keep]
      

      这里的问题与 #1 相同。

    4. 您可以使用花哨的索引来避免多次通过掩码:

       indices = np.flatnonzero(to_keep)
       azim = azim[indices]
       elev = elev[indices]
       rad = rad[indices]
      

    您必须在您的特定系统上对这些进行基准测试。但是,我希望您会发现 #1 和 #3 比 #2 和 #4 慢。

    【讨论】:

      猜你喜欢
      • 2016-01-01
      • 1970-01-01
      • 2010-12-01
      • 2015-07-29
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      相关资源
      最近更新 更多