如何获取Numpy数组置换的逆索引顺序以恢复原数组?
如何计算numpy数组置换的逆索引顺序
咱们先明确需求:已知数组a通过索引order得到b = a[order],要找到inv_order使得b[inv_order]完全还原出原数组a,而且不管a本身是否有序都能生效。
这里有两种高效的实现方法,一起来看看:
方法一:利用np.argsort(简洁直观)
因为order本质是一个0到n-1的排列(n为数组长度),我们可以直接对order做argsort来得到逆索引。argsort的作用是返回数组排序后每个元素的原位置,对于排列来说,这正好就是我们需要的逆映射。
示例代码:
import numpy as np # 构造测试数据(故意用无序数组验证通用性) a = np.array([5, 2, 9, 1, 7]) order = np.random.permutation(len(a)) b = a[order] # 计算逆索引 inv_order = np.argsort(order) # 验证结果 assert np.array_equal(b[inv_order], a) print("还原成功!")
方法二:手动构造逆映射(效率更高)
如果追求极致性能,尤其是处理超大数组时,直接通过赋值构造逆索引的方法是O(n)时间复杂度,比argsort的O(n log n)更快。逻辑很简单:对于order中的每个位置i,order[i]是a[i]在b中的位置,那反过来,inv_order[order[i]]就应该等于i,这样就能把b的元素按原位置还原。
示例代码:
import numpy as np # 构造测试数据 a = np.array([5, 2, 9, 1, 7]) order = np.random.permutation(len(a)) b = a[order] # 计算逆索引 inv_order = np.empty_like(order) inv_order[order] = np.arange(len(order)) # 验证结果 assert np.array_equal(b[inv_order], a) print("还原成功!")
核心逻辑说明
不管用哪种方法,inv_order都需要满足一个关键条件:order[inv_order[k]] = k(或者等价的inv_order[order[k]] = k)。这样当我们取b[inv_order[k]]时,b[inv_order[k]] = a[order[inv_order[k]]] = a[k],正好还原出原数组的第k个元素——这个逻辑和a的内容完全无关,不管a有序还是无序都能生效。
内容的提问来源于stack exchange,提问作者Wei Jiang
相关产品推荐
相关产品推荐

