объединить python элементов списка, где значение равно 1 плюс смещение (маскирование) - PullRequest
4 голосов
/ 16 июня 2020

Цель состоит в том, чтобы найти общий c метод для решения следующей задачи:

У меня есть два python списка одинаковой длины, заполненные нулями и единицами :

detection = [0,0,1,0]     # only examples, they can be of any length
ground_truth = [0,1,0,0]  # and the ones can be at any indizes

и целое число

offset = 1                # this number is also variable

Цель состоит в том, чтобы объединить # offset элементов в detection вокруг элементов, равных 1, а затем объединить те же элементы индекса ground_truth логический or, в результате появляются новые списки:

detection = [0,1]
ground_truth = [0,1]

графическое объяснение:

enter image description here

Фон Информация: Значения обнаружения / истинности относятся к бинарной классификации временного ряда, и идея состоит в том, чтобы иметь гибкую оценку, которая приводит к TP, если detection соответствует ground_truth находится в определенном диапазоне временные шаги (= offset).

Дополнительный пример:

offset = 1
detection = [1,0,0,0,1,1,0]
ground_truth = [0,0,0,1,0,0,0]

приведет к:

detection = [1,0,1]
ground_truth = [0,0,1]

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Я нашел окончательное решение. дополнительные вопросы, которые его решили:

Код:

# Create Mask from Detection and Offset
w = offset*2 +1
mask = np.convolve(detection, np.ones(w), mode='same').clip(0,1).astype(int)

# Create Soft Detection
soft_detection = mask[~((np.diff(mask,prepend=False)==0) & mask==1)].tolist()

# Create Soft Ground Truth
idx = np.flatnonzero(np.r_[True,np.diff(mask)!=0])
soft_ground_truth = np.bitwise_or.reduceat(ground_truth, idx).tolist()
0 голосов
/ 16 июня 2020

Моя первая идея - использовать срез [i-offset:i+offset+1]

Если списки имеют разную длину, вы можете получить более короткую длину

shorter = min(len(detection), len(ground_truth))

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

Я использую [offset:shorter-offset], потому что я предполагал, что вы не хотите проверять, недостаточно ли элементов слева или справа (если элементов меньше, то offset).

indexes = [i for i, val in enumerate(detection[offset:shorter-offset], offset) if val == 1]

И теперь вы можете использовать индексы

for i in indexes:
    #item = detection[i-offset:i] + detection[i+1:i+1+offset]
    # or

    item = detection[i-offset:i+offset+1]
    item.pop(offset) # remove value in the middle

    print('   detection item:', item)

Я не знаю, что вы пытаетесь сделать с or logi c - поэтому пропускаю.


Код - с offset=2

detection    = [0,0,1,0,1,1,0,1,0,1,1]   # longer
ground_truth = [0,1,0,0,0,0,1,0]

#detection    = [0,0,1,0,0,0,1,0,0]       # shorter
#ground_truth = [0,0,1,0,1,1,0,1,0,1,1] 

print('   detection:', detection)
print('ground_truth:', ground_truth)

offset = 2
shorter = min(len(detection), len(ground_truth))

indexes = [i for i, val in enumerate(detection[offset:shorter-offset], offset) if val == 1]
print('indexes:', indexes)

for i in indexes:
    #item = detection[i-offset:i] + detection[i+1:i+1+offset]
    # or

    item = detection[i-offset:i+offset+1]
    item.pop(offset) # remove value in the middle

    print('   detection item:', item)

for i in indexes:
    #item = ground_truth[i-offset:i] + ground_truth[i+1:i+1+offset]
    # or

    item = ground_truth[i-offset:i+offset+1]
    item.pop(offset) # remove value in the middle

    print('ground_truth item:', item)

Результат:

   detection: [0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1]
ground_truth: [0, 1, 0, 0, 0, 0, 1, 0]
indexes: [2, 4, 5]
   detection item: [0, 0, 0, 1]
   detection item: [1, 0, 1, 0]
   detection item: [0, 1, 0, 1]
ground_truth item: [0, 1, 0, 0]
ground_truth item: [0, 0, 0, 1]
ground_truth item: [0, 0, 1, 0]

Вторая идея - использовать shift() для перемещения значения из предыдущего / следующая строка в ту же строку, но в новый столбец. Но с новой информацией я думаю, что создается слишком много новых столбцов, поэтому я удалил его.


Мне было интересно, можно ли это сделать с помощью rolling(window=3), но я не мог создать решение.


Do c: shift , apply , прокатка

...