最大化两个 numpy 数组之间的成对匹配的排序

Ordering that maximizes pair-wise matches between two numpy arrays

假设我们有两个一维 numpy 数组 v1v2。数组长度相等。在这种情况下,数组的 dtype 是 '

我想编写函数get_maximum_match_order

案例:

案例一

这里的数组已经完全匹配,所以顺序是中性的。 v2订单应用后将保持不变。


v1 = np.array(['A', 'B', 'C'])

v2 = np.array(['A', 'B', 'C'])

order = get_maximum_match_order(v1, v2)

order -> np.array([0, 1, 2])

v2[order] -> np.array(['A', 'B', 'C']

案例二

在这种情况下,所有项目都不存在于两个数组中。订单应用于 v2 后,项目 'A' 和 'B' 将匹配。


v1 = np.array(['A', 'C', 'B'])

v2 = np.array(['B', 'A', 'E'])

order = get_maximum_match_order(v1, v2)

order -> np.array([1, 2, 0])

v2[order] -> np.array(['A', 'E', 'B'])

案例三


v1 = np.array(['A', 'B', 'C'])

v2 = np.array(['C', 'B', 'A'])

order = get_maximum_match_order(v1, v2)

order -> np.array([2, 1, 0])

v2[order] -> np.array(['A', 'B', 'C'])

案例4

这里的数组没有任何共同的项目,因此排序是中性的。


v1 = np.array(['A', 'B', 'C'])

v2 = np.array(['D', 'E', 'F'])

order = get_maximum_match_order(v1, v2)

order -> np.array([0, 1, 2])

v2[order] -> np.array(['D', 'E', 'F'])

案例5


v1 = np.array(['A', 'B', 'C'])

v2 = np.array(['A', 'C', 'B'])

order = get_maximum_match_order(v1, v2)

order -> np.array([0, 2, 1])

v2[order] -> np.array(['A', 'B', 'C'])

案例6


v1 = np.array(['A', 'G', 'B'])

v2 = np.array(['B', 'F', 'A'])

order = get_maximum_match_order(v1, v2)

order -> np.array([2, 1, 0])

v2[order] -> np.array(['A', 'F', 'B'])

案例7


v1 = np.array(['A', 'G', 'B', 'C', 'E'])

v2 = np.array(['B', 'F', 'A', 'E', 'C'])

order = get_maximum_match_order(v1, v2)

order -> np.array([2, 1, 0, 4, 3])

v2[order] -> np.array(['A', 'F', 'B', 'C', 'E'])

我已经尝试使用 numpy 的 intersect1d 进行试验,但未能完美地确定这一点。

只需找到对并对齐它们,然后按您喜欢的方式分配其余元素(索引)。

from contextlib import suppress
import numpy as np

def index(vs, v):
    with suppress(IndexError):
        return np.where(vs == v)[0][0]

def get_maximum_match_order(v1, v2):
    ixs = [index(v1, v) for v in v2]
    it = iter(set(range(len(v1))) - set(ixs))
    return np.array([next(it) if ix is None else ix for ix in ixs])

if __name__ == "__main__":
    v1 = np.array(['A', 'G', 'B', 'C', 'E'])
    v2 = np.array(['B', 'F', 'A', 'E', 'C'])
    print(get_maximum_match_order(v1, v2))