问题:窗口切片是将连续信号或长序列分割成多个较短、可能重叠的片段的过程。这个重叠是怎么个重叠方式,是数值上的叠加吗?
一、概念解释:
窗口重叠指的是相邻窗口在时间轴上共享一部分相同的信号样本,而不是对这些样本的值进行数学叠加。
举例说明:
假设:
- 窗口长度L=100L = 100L=100个样本
- 跳跃步长H=50H = 50H=50个样本
- 重叠长度O=L−H=50O = L - H = 50O=L−H=50个样本
那么: - 窗口1:覆盖样本 0-99
- 窗口2:覆盖样本 50-149
- 窗口3:覆盖样本 100-199
注意:窗口1和窗口2共享了样本50-99,但这50个样本在提取时:
- 被分别放入两个不同的窗口
- 在每个窗口内独立处理
- 不是把这些样本的值加起来
2. 可视化展示
3.可视化代码
importnumpyasnpimportmatplotlib.pyplotasplt# 创建简单的示例信号t=np.linspace(0,1,200)signal=np.sin(2*np.pi*5*t)+0.5*np.sin(2*np.pi*10*t)# 窗口参数L=50# 窗口长度H=25# 跳跃步长(50%重叠)overlap=L-H# 重叠长度# 计算窗口数量K=(len(signal)-L)//H+1# 创建图形fig,axes=plt.subplots(2,2,figsize=(12,10))plt.rcParams['font.sans-serif']=['SimHei','Arial Unicode MS','DejaVu Sans']plt.rcParams['axes.unicode_minus']=False# 1. 信号上的窗口位置展示ax1=axes[0,0]ax1.plot(t,signal,'b-',linewidth=2,alpha=0.7,label='原始信号')# 用不同颜色标记前3个窗口colors=['red','green','blue']forkinrange(3):start_idx=k*H end_idx=start_idx+L# 绘制窗口覆盖区域ax1.axvspan(t[start_idx],t[end_idx],alpha=0.3,color=colors[k],label=f'窗口{k+1}'ifk==0elseNone)# 标记窗口边界ax1.axvline(x=t[start_idx],color=colors[k],linestyle='--',alpha=0.7)ax1.axvline(x=t[end_idx],color=colors[k],linestyle='--',alpha=0.7)# 标注重叠区域ifk>0:prev_end_idx=(k-1)*H+L overlap_start=start_idx overlap_end=min(end_idx,prev_end_idx)# 用更深的颜色标注重叠区域ax1.axvspan(t[overlap_start],t[overlap_end],alpha=0.5,color='purple',label='重叠区域'ifk==1elseNone)ax1.set_xlabel('时间 (秒)')ax1.set_ylabel('幅度')ax1.set_title(f'1. 窗口在信号上的位置\n窗口长度={L}, 跳跃={H}, 重叠={overlap}个样本')ax1.legend(loc='upper right')ax1.grid(True,alpha=0.3)# 2. 提取的窗口数据(不重叠显示)ax2=axes[0,1]# 提取前3个窗口的数据windows_data=[]forkinrange(3):start_idx=k*H end_idx=start_idx+L window_signal=signal[start_idx:end_idx]windows_data.append(window_signal)# 在y轴方向偏移显示offset=k*2.5time_window=t[start_idx:end_idx]ax2.plot(time_window,window_signal+offset,color=colors[k],linewidth=2,label=f'窗口{k+1}')# 填充区域ax2.fill_between(time_window,offset,window_signal+offset,alpha=0.2,color=colors[k])ax2.set_xlabel('时间 (秒)')ax2.set_ylabel('幅度(偏移显示)')ax2.set_title('2. 提取的窗口数据(独立显示)')ax2.legend(loc='upper right')ax2.grid(True,alpha=0.3)# 3. 详细展示重叠区域ax3=axes[1,0]# 重点关注窗口1和窗口2的重叠部分win1_idx=0win2_idx=1win1_start=win1_idx*H win1_end=win1_start+L win2_start=win2_idx*H win2_end=win2_start+L# 提取两个窗口的数据win1_signal=signal[win1_start:win1_end]win2_signal=signal[win2_start:win2_end]win1_time=t[win1_start:win1_end]win2_time=t[win2_start:win2_end]# 绘制重叠区域对比overlap_start_idx=win2_start# 重叠开始overlap_end_idx=win1_end# 重叠结束overlap_length=overlap_end_idx-overlap_start_idx# 窗口1的数据(红色)ax3.plot(win1_time,win1_signal,'r-',linewidth=2,label='窗口1')ax3.fill_between(win1_time,0,win1_signal,alpha=0.2,color='red')# 窗口2的数据(绿色),在重叠区域高亮ax3.plot(win2_time,win2_signal,'g-',linewidth=2,label='窗口2')ax3.fill_between(win2_time,0,win2_signal,alpha=0.2,color='green')# 特别标记重叠区域overlap_time=t[overlap_start_idx:overlap_end_idx]overlap_signal_win1=win1_signal[-overlap_length:]# 窗口1的后半部分overlap_signal_win2=win2_signal[:overlap_length]# 窗口2的前半部分# 绘制重叠区域的点对点比较foriinrange(0,overlap_length,5):# 每隔5个点画一条线x_pos=overlap_time[i]y1=overlap_signal_win1[i]y2=overlap_signal_win2[i]ax3.plot([x_pos,x_pos],[y1,y2],'k--',alpha=0.3,linewidth=0.5)# 标记重叠区域边界ax3.axvline(x=t[overlap_start_idx],color='black',linestyle='--',linewidth=1.5,alpha=0.7)ax3.axvline(x=t[overlap_end_idx],color='black',linestyle='--',linewidth=1.5,alpha=0.7)# 填充重叠区域背景ax3.axvspan(t[overlap_start_idx],t[overlap_end_idx],alpha=0.1,color='purple')ax3.set_xlabel('时间 (秒)')ax3.set_ylabel('幅度')ax3.set_title(f'3. 重叠区域详细对比\n{overlap_length}个样本重叠 ({overlap_length/L*100:.0f}%)')ax3.legend(loc='upper right')ax3.grid(True,alpha=0.3)ax3.set_xlim([t[win1_start],t[win2_end]])# 4. 修复的矩阵视角:展示样本如何被多个窗口使用ax4=axes[1,1]ax4.axis('off')# 关闭坐标轴,用于显示示意图# 创建示意图:显示样本索引如何被多个窗口覆盖sample_indices=list(range(200))# 200个样本# 修复:正确初始化window_coveragewindow_coverage={}# 初始化所有样本索引foridxinrange(200):window_coverage[idx]=[]# 计算覆盖关系forkinrange(K):start_idx=k*H end_idx=start_idx+Lforidxinrange(start_idx,min(end_idx,200)):ifidx<200:window_coverage[idx].append(k)# 绘制覆盖关系图y_offset=0sample_display_range=range(60,140)# 显示一部分样本foridxinsample_display_range:windows_covering=window_coverage[idx]# 绘制样本点ax4.plot([idx,idx],[y_offset-0.2,y_offset+0.2],'k-',linewidth=1)ax4.text(idx,y_offset-0.3,str(idx),ha='center',fontsize=8)# 绘制覆盖该样本的窗口forwin_idxinwindows_covering:# 计算窗口位置win_start=win_idx*H win_end=win_start+L# 绘制窗口覆盖条ifwin_start<=idx<win_end:color=colors[win_idx%len(colors)]# 调整y位置,避免重叠y_pos=y_offset+0.5+(win_idx%3)*0.3ax4.plot([win_start,win_end],[y_pos,y_pos],color=color,linewidth=3,alpha=0.7)# 标记连接点ax4.plot([idx,idx],[y_offset+0.2,y_pos],'k:',alpha=0.3,linewidth=0.5)# 标记窗口编号ifidx==win_start+5:# 在窗口开始位置附近标记ax4.text(win_start+2,y_pos+0.05,f'窗口{win_idx+1}',fontsize=7,color=color)# 添加说明文本explanation=""ax4.text(0.05,0.7,explanation,transform=ax4.transAxes,fontsize=9,bbox=dict(boxstyle='round',facecolor='lightyellow',alpha=0.9))ax4.set_xlim([55,145])ax4.set_ylim([-1,3])ax4.set_title('4. 样本被多个窗口覆盖示意图')plt.tight_layout()plt.show()