关于python:从列表中返回差异!= 2的值

Return values from a list where difference != 2

我有一个清单,例如my_list = [1, 3, 5, 7, 14, 16, 18, 22, 28, 30, 32, 41, 43]

我想要一个函数,该函数将返回列表中的所有值,其中该值与先前值之差不等于2,例如该函数将为上述列表返回[1, 14, 22, 28, 41]。请注意,my_list的第一个值将始终显示为输出的第一个值。输入列表的长度不为零,且最多为100。

到目前为止,我有这个:

1
2
3
4
5
6
7
def get_output(array):
    start = [array[0]]
    for i in range(1, len(array)-1):
        if (array[i] - array[i-1]) != 2:
            start.append(array[i])

    return start

是否存在一个更快的矢量化解决方案,请记住我将将此功能应用于数千个输入数组?


为避免使用效率不高的np.concat,请使用np.ediff1而不是np.diff,后者需要使用to_begin自变量附加到结果前:

1
2
3
4
>>> my_list = [1, 3, 5, 7, 14, 16, 18, 22, 28, 30, 32, 41, 43]
>>> arr = np.array(my_list)
>>> np.ediff1d(arr, to_begin=0)
array([0, 2, 2, 2, 7, 2, 2, 4, 6, 2, 2, 9, 2])

现在,使用布尔索引:

1
2
>>> arr[np.ediff1d(arr, to_begin=0) != 2]
array([ 1, 14, 22, 28, 41])


您可以对NumPy数组和np.diff使用布尔数组索引来获取值之间的差:

1
2
3
4
5
6
7
>>> my_list = [1, 3, 5, 7, 14, 16, 18, 22, 28, 30, 32, 41, 43]
>>> import numpy as np
>>> my_arr = np.array(my_list)
>>> my_mask = np.ones(my_arr.shape, dtype=bool)  # initial mask
>>> my_mask[1:] = np.diff(my_arr) != 2           # set all elements to False that have a difference of 2
>>> my_arr[my_mask]                              # mask the array
array([ 1, 14, 22, 28, 41])


除了您可以手动添加的第一个元素(尽管按照Azat Ibrakov的注释实际上没有意义),您还可以使用np.where

1
2
3
4
a = np.array([1, 3, 5, 7, 14, 16, 18, 22, 28, 30, 32, 41, 43])
a[np.where(a[1:] - a[:-1] != 2)[0] + 1]

array([14, 22, 28, 41])

添加第一个元素:

1
2
3
[a[0]] + list(a[np.where(a[1:] - a[:-1] != 2)[0] + 1])

[1, 14, 22, 28, 41]


1
2
3
4
5
6
import numpy as np

my_list = [1, 3, 5, 7, 14, 16, 18, 22, 28, 30, 32, 41, 43]
a = np.array(my_list)
output = a[[True] + list(a[1:]-a[:-1] != 2)]
print(output)