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

如何用NumPy/SciPy映射数组值消除间隙并随机重排?

嘿,这两个需求都能用NumPy完美解决,我来给你一步步拆解:

1. 生成无值间隙且保持原顺序的映射数组

你的核心需求是:把原数组中每个不同元素映射到连续的整数(从0开始,无缺失),相同元素对应同一个值,同时完全保留原数组的元素顺序。

用NumPy的np.unique()函数就能直接搞定,关键是用到它的return_inverse参数——这个参数会返回原数组每个元素在排序后的唯一元素数组中的索引,刚好匹配你给出的示例输出:

import numpy as np

a = np.array([0,0,1,1,4,4,4,4,5,1891,7])
# 获取排序后的唯一元素,以及原元素对应的映射索引
_, arr_map = np.unique(a, return_inverse=True)
print(arr_map)  # 输出: [0 0 1 1 2 2 2 2 3 5 4]

如果你的需求是按元素首次出现的顺序分配映射值(而非按数值大小排序),可以稍微调整逻辑,用return_index参数先锁定首次出现的位置,再生成映射:

# 获取每个唯一元素首次出现的索引
_, idx = np.unique(a, return_index=True)
# 按首次出现顺序排序得到唯一元素列表
unique_ordered = a[np.sort(idx)]
# 生成每个元素对应的映射值
arr_map = np.searchsorted(unique_ordered, a)
print(arr_map)  # 输出: [0 0 1 1 2 2 2 2 3 4 5]

这个版本里,1891会被映射为4,7映射为5,因为它们首次出现的顺序在5之后。

2. 打乱映射后的数值

要交换/打乱映射后的数值,本质就是定义一个置换规则,用置换数组重新映射原结果即可。

比如你想要把示例中的[0,0,1,1,2,2,2,2,3,5,4]转换成[0,0,3,3,5,5,5,5,4,1,2],可以先自定义置换规则,再应用到原映射结果上:

# 原映射结果
arr_map = np.array([0,0,1,1,2,2,2,2,3,5,4])
# 置换数组:索引是原映射值,对应的值是新的映射值
perm = np.array([0, 3, 5, 4, 2, 1])
# 应用置换规则
shuffled_arr = perm[arr_map]
print(shuffled_arr)  # 输出: [0 0 3 3 5 5 5 5 4 1 2]

如果想要随机打乱映射值(保证每个原映射值对应唯一的新值,无冲突),可以用np.random.permutation()生成随机置换:

# 获取映射值的范围(0到最大映射值)
n = arr_map.max() + 1
# 生成随机置换数组
random_perm = np.random.permutation(n)
# 应用随机置换
random_shuffled = random_perm[arr_map]
print(random_shuffled)  # 输出类似: [1 1 0 0 3 3 3 3 4 2 5](每次运行结果不同)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:01:44