如何用Numpy向量化实现不连续数组转连续数组?
纯Numpy向量化实现连续分组编号
当然可以用纯Numpy实现完全向量化的操作,而且效率比for循环高得多——毕竟Numpy的底层是C实现的,避免了Python层面的循环开销,处理大数组时优势特别明显。
实现代码
import numpy as np a = np.array([1,1,1,3,3,6,6,6,6,6,6]) def vectorized_group(a): # 1. 标记元素变化的位置:当前元素与前一个不同则为True change_points = a[1:] != a[:-1] # 2. 给开头补一个True(第一个元素属于新分组的起点) change_points = np.concatenate([[True], change_points]) # 3. 对变化点累加,再减1得到从0开始的连续编号 return np.cumsum(change_points) - 1 b = vectorized_group(a) print(b) # 输出: [0 0 0 1 1 2 2 2 2 2 2]
逻辑解释
- 标记变化点:
a[1:] != a[:-1]生成一个布尔数组,长度比原数组少1,每个位置标记当前元素是否和前一个元素不同。 - 补全起点:因为第一个元素没有前一个元素,默认是新分组的开始,所以在布尔数组开头加
True,让长度和原数组一致。 - 累加生成编号:
np.cumsum会把布尔值视为0(False)和1(True)进行累加,每次遇到变化点就加1,最后减1是为了让编号从0开始,正好符合你的需求。
避坑提醒
别用np.unique(a, return_inverse=True)[1]来实现!这个方法会先对数组元素去重排序,返回的是元素在排序后去重数组中的索引,和你需要的「按连续出现顺序分组」逻辑不符。比如如果数组是[3,3,1,1],这个方法会返回[1,1,0,0],但你实际需要的是[0,0,1,1]。
内容的提问来源于stack exchange,提问作者deepAgrawal
相关产品推荐
相关产品推荐

