在numpy数组Python之间找到一对匹配

时间:2017-07-09 14:03:33

标签: python arrays numpy

我在Python中有一个numpy数组,其中包含分类问题的标签。在两个初始相同数组的连接之后派生的数组。

labels = np.concatenate((labels1, labels2)) #labels1 and labels2 are identical

我想生成正/负对,它将包含标签中的所有索引(label1和labels2相等)以及带负数的对。例如,如果我的输入如下:

labels = {1, 1, 2, 2, 3, 1, 1, 2, 2, 3} # labels1 = labels2 = {1, 1, 2, 2, 3}

然后我想作为正面对返回:

positive_pairs = {{1, 6}, {1, 7}, {2, 6}, {2, 7}, {3, 8}, {3, 9}, {4, 8}, {4, 9}, {5, 10}} # i dont want to have {1,2} or {3, 4} in within the positives
negative_pairs = {{1, 8}, {1, 9}, ...}

我怎么能在python中这样做?

编辑:标签1和标签2不相等的情况是什么?

4 个答案:

答案 0 :(得分:3)

这是positive_pairs的解决方案:

labels1 = np.array([1, 1, 2, 2, 3])
length1 = len(labels1)
positive_pairs = []
for ii, label in enumerate(labels1, 1):
    for other in np.where(labels1 == label)[0] + length1 + 1:
        positive_pairs.append((ii, other))

negative_pairs留作练习。

答案 1 :(得分:3)

你可以像这样完成它

labels_1 = np.array([1,1,2,2,3])
labels_2 = np.array([1,1,2,2,3])
n = len(labels_1)
positive_pairs = [(i1+1, i2+n+1) for i1, l in enumerate(labels_1) 
                                 for i2 in np.where(labels_2 == l)[0]]
  

[(1,6),(1,7),(2,6),(2,7),...]

negative_pairs = [(i1+1, i2+n+1) for i1, l in enumerate(labels_1) 
                                 for i2 in np.where(labels_2 != l)[0]]
  

[(1,8),(1,9),(1,10),(2,8),...]

虽然,我不确定这是最有效的方法。

答案 2 :(得分:2)

outp = []
len1 = len(labels) // 2 # assume initially labels was [label1, label1]
label1 = labels[:len1]
label2 = labels[len1:]
set1 = set(label1)
for v in set1:
    eq1 = np.where(label1 == v)[0] + 1
    eq2 = np.where(label2 == v)[0] + len1 + 1
    outp.append(np.transpose([np.tile(eq1, len(eq2)), np.repeat(eq2, len(eq1))]))
outp = np.concatenate(outp).tolist()

# Edit: Find "negative pairs"
eq3 = np.indices((len1, ))[0][np.in1d(label2, list(set1), invert=True)] + len1 + 1
outn = np.transpose([np.tile(np.arange(len1), len(eq3)), np.repeat(eq3, len1)]).tolist()

答案 3 :(得分:1)

我的解决方案使用了numpy广播和np.where()

x, y = np.where(label1[np.newaxis, :] == label2[:, np.newaxis])
result = np.vstack([x, y+len(label1)]).T + 1

我认为这是解决问题的有效/无条件方式。但是,tarashypka的解决方案在更大的数据集上更快。 (任何人都知道为什么?)

def where_method(a, b):
    x, y = np.where(a[np.newaxis, :] == b[:, np.newaxis])
    return np.vstack([x, y+len(labels1)]).T + 1

def for_append_method(a, b):
    length1 = len(a)
    positive_pairs = []
    for ii, label in enumerate(a, 1):
        for other in np.where(b == label)[0] + length1 + 1:
            positive_pairs.append((ii, other))
    return positive_pairs

labels1 = np.sort(np.random.randint(low=10, high=7500, size=10000))
labels2 = labels1

%timeit where_method(labels1, labels2)
%timeit for_append_method(labels1, labels2)
326 ms ± 2.98 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
122 ms ± 1.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)