问题描述
我在[0,20]
区间有一些要点
我有一个window_size=3
大小的窗口,可以在上述间隔内移动。因此,窗口的开始-我们将start
限制为[0,17]
。
假设我们下面有一些points
:
points = [1.4,1.8,11.3,11.8,12.3,13.2,18.2,18.3,18.4,18.5]
如果我们希望至少获得min_points=4
个点,那么这些窗口的起始范围(我手动找到)的解决方案是:
suitable_starts = [[10.2,11.3],[15.5,17.0]]
即大小3
窗口的开始可以从10.2
到11.3
,也可以从15.5
到17.0
。 通常,窗口的相应末端将只是起始范围的+3
。
我正在寻找一种方法,以巧妙的numpy
或scipy
或其他功能来快速解决此问题。
我要寻找的常规功能是:
get_start_windows(interval = [0,20],window_size = 3.0,points = [1.4,18.5],min_points = 4
return suitable_starts # suitable_starts = [[10.2,17.0]]
注意:
正如评论中的某人指出的那样,有时在某些特殊情况下,点之间的窗口大小正好相距。但是实际上,这些点是双浮点,不可能将它们精确地分开window_size,因此可以忽略它们。
这些特殊示例包括:
points = [1.4,14.2,15.2,16.2,17.2,18.5]
但是可以安全地忽略这些。
解决方法
经过一番努力,我想出了这个解决方案。
首先要进行一些解释,以及思想顺序:
- 理想情况下,我们希望设置窗口大小并将其从最左边的可接受点滑动到最右边的可接受点,并在窗口
min_points
时开始计数,并在{{1}时结束计数}不再在其中(将其想象成抽搐的罪犯) - 基本陷阱是我们希望离散化滑动,因此这里的诀窍是仅检查点数可以低于或高于
min_points
的情况,这意味着每次出现元素或{{ 1}}(如min_points
反映) - 然后遍历
window_size
并在每个时间间隔内采样满足第一个条件的最后一个条件
因此,如上所述编写了以下代码:
optional_starts
输出:
optional_starts
每个2个相应的元素反映间隔的开始和结束
,因此,在给出有关“间隔”性质的其他信息之后,我提出以下解决方案,该解决方案假定间隔间隔至少为window_size
:
import numpy as np
def get_start_windows(inter,ws,p,mp):
# Initialize list of suitable start ranges
start_ranges = []
# Determine possible intervals w.r.t. to window size
int_start = np.insert(np.array([0,p.shape[0]]),1,(np.argwhere(np.diff(p) > ws) + 1).squeeze()).tolist()
# Iterate found intervals
for i in np.arange(len(int_start)-1):
# The actual interval
int_ = p[int_start[i]:int_start[i+1]]
# If interval has less than minimum points,reject
if int_.shape[0] < mp:
continue
# Determine first and last possible starting point
first = max(inter[0],int_[mp-1] - ws)
last = min(int_[-mp],inter[1] - ws)
# Add to list of suitable start ranges
start_ranges.append((first,last))
return start_ranges
# Example 1
interval = [0,20]
window_size = 3.0
min_points = 4
points = [1.4,1.8,11.3,11.8,12.3,13.2,18.2,18.3,18.4,18.5]
print(get_start_windows(interval,window_size,np.array(points),min_points))
# Example 2
points = [1.4,1.9,2.1,min_points))
# Example 3
points = [1.4,1.5,1.6,1.7,2.0,3.49]
print(get_start_windows(interval,min_points))
(代码可能已经过优化,我没有注意...)
输出:
[(10.2,11.3),(15.5,17.0)]
[(0,1.4),(10.2,1.9)]
希望该解决方案涵盖了所需的案例。
-------------------------------------
System information
-------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.5
NumPy: 1.19.2
-------------------------------------