Наиболее эффективный с вычислительной точки зрения способ классификации сравнения двух массивов numpy из 1 и 0; если индекс обоих содержит 1 или 0 и т. д.

avatar
SantoshGupta7
9 августа 2021 в 01:06
66
3
1

Скажем, у меня есть два пустых массива

prediction = np.array([1, 0, 0, 1, 1, 0, 1, 1, 1])
groundtrue = np.array([1, 0, 1, 0, 1, 1, 0, 0, 1])

Я хотел бы сравнить два массива, включая классификацию каждого сравнения индексов. Итак, я хочу классифицировать, если оба prediction и groundtrue имеют 1, или если prediction имеет 1 и groundtrue имеет 0, или наоборот, и т. д.

Итак, пример желаемого результата может выглядеть следующим образом

comparison = np.array([1, 2, 3, 4, 1, 3, 4, 4, 1])

1 используется, если оба имеют 1. 2 используется, если оба имеют 0s. 3 используется, если prediction имеет 0, а groundtrue имеет 1. и т. д.

Самый простой способ - использовать цикл и напрямую сравнивать каждый индекс, но кажется, что numpy может иметь некоторые операторы, которые могут делать это очень эффективно с точки зрения вычислений и гораздо меньше строк кода

np.where(prediction == groundtrue, 1, 0)

Можно получить массив, в котором два значения равны или нет, но я не вижу, чтобы он давал разные типы сравнений.

Источник
Psidom
9 августа 2021 в 01:13
4

prediction + 2 * groundtrue даст классификацию, хотя может быть не в том порядке, в котором вы хотели.

SantoshGupta7
9 августа 2021 в 01:18
2

Это решает мой ответ. Вы можете отправить это как ответ, и я выберу его.

Ответы (3)

avatar
Psidom
9 августа 2021 в 01:22
3

Поскольку у вас есть только 0 и 1 в prediction и groundtrue, всего будет только 4 случая. Следовательно, вы можете создать классификацию с помощью:

prediction + 2 * groundtrue
# array([3, 0, 2, 1, 3, 2, 1, 1, 3])

Это будет не тот порядок, что в OP, но достаточный, чтобы различать разные случаи.

  • 0, если оба prediction и groudtrue равны 0;
  • 1, если groudtrue равно 0 и prediction равно 1;
  • 2, если groudtrue равно 1 и prediction равно 0;
  • 3, если оба равны 1;
avatar
Alex Alex
9 августа 2021 в 01:38
1

Вы можете попробовать использовать такой код:

import numpy as np
prediction = np.array([1, 0, 0, 1, 1, 0, 1, 1, 1])
groundtrue = np.array([1, 0, 1, 0, 1, 1, 0, 0, 1])
lut=np.array([2,4,3,1]) #look up table
pow_two=2**np.arange(2)
comparison=lut[np.dot(pow_two, np.vstack((prediction, groundtrue)))]
avatar
jakub
9 августа 2021 в 01:11
2

Это можно сделать с помощью логических масок.

import numpy as np

prediction = np.array([1, 0, 0, 1, 1, 0, 1, 1, 1])
groundtrue = np.array([1, 0, 1, 0, 1, 1, 0, 0, 1])

comparison = np.zeros_like(prediction)
comparison[(prediction==1) & (groundtrue==1)] = 1
comparison[(prediction==0) & (groundtrue==0)] = 2
comparison[(prediction==0) & (groundtrue==1)] = 3
comparison[(prediction==1) & (groundtrue==0)] = 4
comparison  # array([1, 2, 3, 4, 1, 3, 4, 4, 1])

Следующее дает тот же результат, что и выше, но вам нужно вычислить только две маски. Это предполагает, что предсказание и наземная правда могут иметь значения только 0 или 1.

import numpy as np

prediction = np.array([1, 0, 0, 1, 1, 0, 1, 1, 1])
groundtrue = np.array([1, 0, 1, 0, 1, 1, 0, 0, 1])

pred0 = prediction == 0
ground0 = groundtrue == 0
comparison = np.zeros_like(prediction)
comparison[~pred0 & ~ground0] = 1
comparison[pred0 & ground0] = 2
comparison[pred0 & ~ground0] = 3
comparison[~pred0 & ground0] = 4
comparison  # array([1, 2, 3, 4, 1, 3, 4, 4, 1])

Маски будут иметь логические значения, где каждое значение указывает, верно ли условие в исходном массиве.

x = np.array([0, 1])
x == 0  # array([ True, False])

Операция & будет вычислять логическое И обоих логических массивов. Для получения дополнительной информации см. numpy.logical_and.

Затем можно использовать логическую маску для подмножества определенных значений. Мы можем присвоить этому подмножеству индексов новое значение.

x = np.array([0, 1])
x[x==0] = 2
x  # array([2, 1])