p
,它的逆置换(inverse permutation)是一个排列 invp
,满足 invp[p[i]] = i
和 p[invp[i]] = i
对所有 i
成立。'''
计算一个排列的逆排列
给定一个排列 p,它的逆排列是一个排列 invp,满足 invp[p[i]] = i 和 p[invp[i]] = i 对所有 i 成立
'''
def invpermute(p):
"""
inverse permutation
"""
p = np.asarray(p)
invp = np.empty_like(p)
for i in range(p.size):
invp[p[i]] = i
#对于每个 i,设置 invp 在 p[i] 的位置上的值为 i
return invp
p = [2, 0, 1]
invp = invpermute(p)
invp
#[1, 2, 0]
反之亦可
假设我们有如下序列:
seqs = ["apple", "banana", "cherry", "date", "fig"]
他们的长度分别为:
lengths = [5, 6, 6, 4, 3]
为了高效地进行批处理,对这些序列按长度进行排序:
sorted_seqs = ["fig", "date", "apple", "banana", "cherry"]
这时,我们需要一个排列索引(按照长度排序后的索引结果)来跟踪这个排序操作:
idx = [4, 3, 0, 1, 2]
#排序后的第0个元素是原来的第4个元素,以此类推
在RNN处理后,我们得到的输出也是按这个顺序排序的。为了将输出恢复到与原始输入相同的顺序,我们需要使用逆排列:
invp = [2, 3, 4, 1, 0]
'''
invp的计算:
invp的第idx[0](4)个元素是0
invp的第idx[1](3)个元素是1
。。。
'''
使用这个逆排列,我们可以将输出重新排序,使其与原始输入的顺序相匹配。
比如RNN之后,得到的输出序列是
outputs = ["output_fig", "output_date", "output_apple", "output_banana", "output_cherry"]
那么 使用逆排列,我们可以将输出重新排序到原始输入的顺序:
original_order_outputs = [outputs[i] for i in invp]
# 返回:['output_apple', 'output_banana', 'output_cherry', 'output_date', 'output_fig']
这样,original_order_outputs
就和 seqs
的顺序一致了。
所以,通过使用逆置换,我们可以确保无论输入序列如何被排序或重排,我们总是可以使用逆置换来恢复原始的顺序。这在处理与序列关联的目标或标签时非常有用,因为我们需要确保输入和标签的顺序始终保持一致。