You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从NumPy数组中提取指定数量的关键变化点以实现压缩?

提取NumPy数组指定数量的关键特征点方法

方法1:基于窗口方差的自适应采样

核心思路:计算数组局部窗口的方差,方差越大代表该区域数据变化越剧烈,优先保留这些区域的点,最终凑够指定数量。

import numpy as np

def variance_based_sample(arr, n):
    arr_len = len(arr)
    if n >= arr_len:
        return np.arange(arr_len)
    
    # 设置滑动窗口大小,可根据数据规模调整
    window_size = max(2, arr_len // (n * 2))
    # 计算每个位置的局部窗口方差
    variances = np.array([
        np.var(arr[max(0, i - window_size//2):min(arr_len, i + window_size//2 + 1)]) 
        for i in range(arr_len)
    ])
    
    # 选出方差最大的n个索引并排序,保证顺序不变
    top_indices = np.argsort(variances)[-n:]
    top_indices.sort()
    return top_indices

# 示例调用
array = np.random.randn(100)  # 替换为你的目标数组
n = 40
selected_indices = variance_based_sample(array, n)
selected_points = array[selected_indices]

方法2:迭代调整epsilon的RDP算法

原RDP无法指定输出点数,可通过二分法迭代调整epsilon参数,直到输出点数满足要求。

from rdp import rdp  # 需先安装:pip install rdp

def rdp_fixed_points(arr, n):
    arr_len = len(arr)
    if n >= arr_len:
        return np.arange(arr_len)
    if n <= 2:
        return np.array([0, arr_len - 1])
    
    # 将一维数组转为二维点集(x为索引,y为数组值)
    points = np.column_stack((np.arange(arr_len), arr))
    
    # 二分法寻找合适的epsilon
    low = 0.0
    high = np.max(arr) - np.min(arr)
    best_indices = None
    
    for _ in range(20):  # 迭代20次足够收敛
        mid = (low + high) / 2
        simplified = rdp(points, epsilon=mid)
        simplified_indices = simplified[:, 0].astype(int)
        
        if len(simplified_indices) == n:
            return simplified_indices
        elif len(simplified_indices) > n:
            # 点数过多,增大epsilon简化更多点
            low = mid
        else:
            # 点数过少,减小epsilon保留更多点
            high = mid
        best_indices = simplified_indices
    
    # 若未刚好命中,调整最近结果凑够数量
    if len(best_indices) > n:
        return best_indices[:n]
    else:
        remaining = n - len(best_indices)
        mask = np.ones(arr_len, dtype=bool)
        mask[best_indices] = False
        remaining_indices = np.where(mask)[0]
        # 补充方差最大的剩余点
        variances = np.array([np.var(arr[max(0,i-1):min(arr_len,i+2)]) for i in remaining_indices])
        add_indices = remaining_indices[np.argsort(variances)[-remaining:]]
        final_indices = np.sort(np.concatenate([best_indices, add_indices]))
        return final_indices

# 示例调用
array = np.random.randn(100)
n = 40
selected_indices = rdp_fixed_points(array, n)
selected_points = array[selected_indices]

方法3:基于斜率变化的采样

计算相邻点的斜率变化率,变化率大的点对应数据突变位置,优先保留,再补充均匀采样点凑数。

def slope_based_sample(arr, n):
    arr_len = len(arr)
    if n >= arr_len:
        return np.arange(arr_len)
    
    # 计算相邻斜率及斜率变化值
    slopes = np.diff(arr) / np.diff(np.arange(arr_len))
    slope_changes = np.abs(np.diff(slopes))
    change_indices = np.arange(1, arr_len - 1)
    
    # 保留首尾点,再选斜率变化最大的k个点
    k = n - 2
    top_change_indices = change_indices[np.argsort(slope_changes)[-k:]]
    selected_indices = np.sort(np.concatenate([[0], top_change_indices, [arr_len - 1]]))
    
    # 若数量不足,补充随机选的剩余点
    if len(selected_indices) < n:
        extra = n - len(selected_indices)
        mask = np.ones(arr_len, dtype=bool)
        mask[selected_indices] = False
        extra_indices = np.random.choice(np.where(mask)[0], extra, replace=False)
        selected_indices = np.sort(np.concatenate([selected_indices, extra_indices]))
    
    return selected_indices

# 示例调用
array = np.random.randn(100)
n = 40
selected_indices = slope_based_sample(array, n)
selected_points = array[selected_indices]

内容的提问来源于stack exchange,提问作者user3379546

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:25:16