代码之家  ›  专栏  ›  技术社区  ›  JDS

在数组中选择n个均匀分布的元素,包括第一个和最后一个

  •  8
  • JDS  · 技术社区  · 6 年前

    我有一个任意长度的数组,我想选择其中的n个元素,均匀地隔开(大约,因为n可能是偶数,数组长度可能是素数,等等),包括第一个 arr[0] 元素和最后一个 arr[len-1] 元素。

    例子:

    >>> arr = np.arange(17)
    >>> arr
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16])
    

    然后我想做一个像下面这样的函数 numElems 在数组中均匀分布,其中必须包括第一个和最后一个元素:

    GetSpacedElements(numElems = 4)
    >>> returns 0, 5, 11, 16
    

    这有道理吗?

    我试过了 arr[0:len:numElems] (即使用数组 start:stop:skip 符号)和一些细微的变化,但我没有得到我在这里寻找的:

    >>> arr[0:len:numElems]
    array([ 0,  4,  8, 12, 16])
    

    >>> arr[0:len:numElems+1]
    array([ 0,  5, 10, 15])
    

    我不在乎中间元素到底是什么,只要它们之间的间隔是均匀的,比如1。但是获得正确数量的元素,包括索引0和最后一个索引,是至关重要的。

    希望有人能帮我找到一个快速的一行,谢谢!

    3 回复  |  直到 6 年前
        1
  •  11
  •   ddelange    6 年前

    若要获取等距索引的列表,请使用 np.linspace :

    idx = np.round(np.linspace(0, len(arr) - 1, numElems)).astype(int)
    

    下一步,索引回 arr 要获取相应的值:

    arr[idx]
    

    在强制转换为整数之前,请始终使用舍入。内部, linspace 电话 astype 当提供dtype参数时。因此,这种方法是 不是 相当于:

    # this simply truncates the non-integer part
    idx = np.linspace(0, len(array) - 1, numElems).astype(int)
    idx = np.linspace(0, len(arr) - 1, numElems, dtype='int')
    
        2
  •  2
  •   Justin    6 年前

    getSpaceDelements()函数还应该接受数组,以避免代码中其他地方出现不幸的副作用。也就是说,函数需要如下所示:

    import numpy as np
    
    def GetSpacedElements(array, numElems = 4):
        out = array[np.round(np.linspace(0, len(array)-1, numElems)).astype(int)]
        return out
    
    arr = np.arange(17)
    print(array)
    spacedArray = GetSpacedElements(arr, 4)
    print (spacedArray)
    
        3
  •  1
  •   ddelange    6 年前

    如果您想了解有关查找与所查找的值匹配的索引的更多信息,还可以查看 numpy.argmin numpy.where . 实施前者:

    import numpy as np
    
    test = np.arange(17)
    
    def nearest_index(array, value):
        return (np.abs(np.asarray(array) - value)).argmin()
    
    def evenly_spaced_indices(array, steps):
        return [nearest_index(array, value) for value in np.linspace(np.min(array), np.max(array), steps)]
    
    print(evenly_spaced_indices(test,4))
    

    您应该记住,对于您最初提出的问题,这是一个不必要的函数调用量,正如coldspeed快速演示的那样。 np.round 直观地循环到最接近的匹配整数作为索引,实现类似的过程,但在C++中优化。如果您也对索引感兴趣,可以让您的函数简单地返回:

    import numpy as np
    
    def GetSpacedElements(array, numElems=4, returnIndices=False):
        indices = np.round(np.linspace(0, len(arr) - 1, numElems)).astype(int)
        values = array[indices]
        return (values, indices) if returnIndices else (values)
    
    arr = np.arange(17) + 42
    print(arr)
    print(GetSpacedElements(arr, 4))                            # values only
    print(GetSpacedElements(arr, 4, returnIndices=True)[0])     # values only
    print(GetSpacedElements(arr, 4, returnIndices=True)[1])     # indices only