如何从较大numpy.ndarray中移除其随机采样生成的小子数组元素
NumPy从原数组移除随机采样子集的实现方案
核心逻辑:NumPy原生不支持ndarray直接调用remove/delete做批量按值移除,通过布尔掩码过滤的向量化方案可以高效实现需求,分两类常见场景处理:
- 注意:所有方案均为向量化实现,避免Python层循环,大数据量下性能远高于逐元素遍历删除
场景1:一维无重复值数组
如果你的数组是一维,且采样时不存在重复抽取同值的情况,直接用np.isin生成反选掩码即可:
import numpy as np # 测试数据:原大数组、随机采样子集 big_array = np.array([2,5,7,1,8,4,9,3,6]) sample_subset = np.array([5,1,9]) # 生成过滤掩码:保留所有不在采样子集中的元素 filter_mask = ~np.isin(big_array, sample_subset) res = big_array[filter_mask] print(res) # 输出 [2 7 8 4 3 6]
该方法的局限:如果原数组存在和子集取值相同但未被采样到的元素,会被一并误删,仅适合值唯一的采样场景。
场景2:多维数组/存在重复值需精准匹配
如果是多维数组(比如坐标点、特征矩阵),或者一维数组存在重复值、需要精准删除你实际采样到的对应条目(而非所有同值元素),通过数组视图转换实现整行/整元素匹配:
import numpy as np # 测试数据:shape为(7,2)的二维点集原数组,存在重复点[2,3] big_array = np.array([[1,2], [2,3], [4,5], [6,7], [8,9], [2,3], [10,11]]) # 随机采样子集,包含1个重复点[2,3],仅需删除采样到的这1个,保留剩下的同值点 sample_subset = np.array([[4,5], [8,9], [2,3]]) # 将数组转换为单void类型视图,实现整行元素的直接比较 void_dt = np.dtype((np.void, big_array.dtype.itemsize * big_array.shape[-1])) big_view = big_array.view(void_dt).squeeze() sample_view = sample_subset.view(void_dt).squeeze() # 匹配采样元素对应索引,仅删除和采样数量一致的匹配条目,避免误删重复值 match_indices = np.where(np.isin(big_view, sample_view))[0][:len(sample_view)] filter_mask = np.ones(len(big_array), dtype=bool) filter_mask[match_indices] = False res = big_array[filter_mask] print(res) # 输出 [[ 1 2] [ 2 3] [ 6 7] [10 11]] # 未被采样的重复点[2,3]正常保留
内容的提问来源于stack exchange,提问作者Nmala
相关产品推荐
相关产品推荐

