组合 python 列表元素,其中值为 1 加上偏移量(掩码)
combine python list elements where value is 1 plus an offset (masking)
目标是找到解决以下任务的通用方法:
我有 两个 python 相同长度的列表,用 0 和 1 填充:
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
目标是将 detection
中的 #offset
个元素合并到等于 1
的元素周围
然后组合 ground_truth
逻辑 or
的相同索引元素,生成新列表:
detection = [0,1]
ground_truth = [0,1]
图解说明:
背景信息: 检测/地面真值属于时间序列的二元分类,其想法是进行灵活的评估,如果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]
我的第一个想法是使用 slice [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
逻辑做什么 - 所以我跳过它。
代码 - 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()
将值从 previous/next 行移动到同一行,但移动到新列。但是有了新信息,我认为它创建了太多新列,所以我删除了它。
我想知道是否可以用 rolling(window=3)
完成,但我无法创建解决方案。
我找到了最终的解决方案。
解决它的子问题:
代码:
# 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()
目标是找到解决以下任务的通用方法:
我有 两个 python 相同长度的列表,用 0 和 1 填充:
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
目标是将 detection
中的 #offset
个元素合并到等于 1
的元素周围
然后组合 ground_truth
逻辑 or
的相同索引元素,生成新列表:
detection = [0,1]
ground_truth = [0,1]
图解说明:
背景信息: 检测/地面真值属于时间序列的二元分类,其想法是进行灵活的评估,如果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]
我的第一个想法是使用 slice [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
逻辑做什么 - 所以我跳过它。
代码 - 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()
将值从 previous/next 行移动到同一行,但移动到新列。但是有了新信息,我认为它创建了太多新列,所以我删除了它。
我想知道是否可以用 rolling(window=3)
完成,但我无法创建解决方案。
我找到了最终的解决方案。 解决它的子问题:
代码:
# 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()