如何按出现顺序重新编号数组中的不相交连续区块
连续区块的重新编号:优雅实现方案
给定一个由连续相同元素组成区块的一维数组,我们需要将每个区块按出现顺序重新编号(从0开始递增),示例如下:
输入数组:
import numpy as np x = np.asarray([ 1, 1, 1, 1, 9, 9, 9, 3, 3, 3, 3, 3, 5, 5, 5, ])
目标数组:
desired = np.asarray([ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, ])
以下是两种优雅的实现方式,分别利用Numpy的向量化特性和纯Python迭代:
一、Numpy向量化实现(推荐,高效处理大数据)
通过识别区块变化点并累加生成编号,完全用向量化操作避免Python循环,性能优势显著:
# 标记区块变化的位置:当前元素与前一个元素不同的位置(开头补False) change_points = np.concatenate([[False], x[1:] != x[:-1]]) # 对变化点累加,再减1让第一个区块从0开始 result = np.cumsum(change_points) - 1 # 验证结果 print(np.array_equal(result, desired)) # 输出 True
原理说明:
x[1:] != x[:-1]生成布尔数组,每个位置标记是否发生区块切换;np.cumsum对布尔数组累加(True视为1,False视为0),每次切换区块时编号自动加1;- 最后减1是因为初始累加从0开始,第一个区块的变化点为False,累加结果为0,减1后正好从0开始编号。
二、纯Python迭代实现(适合小数据量,直观易懂)
如果不需要Numpy依赖,可通过简单迭代完成:
result = [] current_id = 0 prev_val = x[0] result.append(current_id) for val in x[1:]: if val != prev_val: current_id += 1 result.append(current_id) prev_val = val result = np.asarray(result) # 按需转换为Numpy数组 # 验证结果 print(np.array_equal(result, desired)) # 输出 True
内容的提问来源于stack exchange,提问作者shadowtalker
相关产品推荐
相关产品推荐

