我在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不相等的情况是什么?
答案 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)