组合python列表元素,其中值为1加上偏移量(掩蔽)

组合python列表元素,其中值为1加上偏移量(掩蔽),python,list,reduce,masking,Python,List,Reduce,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 目标是将检测中

目标是找到解决以下任务的通用方法:

我有两个长度相同的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
目标是将
检测
中的#
偏移
元素与等于
1
然后将
ground\u truth
逻辑
的相同索引元素组合在一起,生成新列表:

detection = [0,1]
ground_truth = [0,1]
图形说明:

背景信息:检测/地面真值属于时间序列的二元分类,其思想是,如果
检测符合
地面真值
在一定的时间步长范围内(
偏移量
),则进行灵活的评估,从而产生TP

附加示例:

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

现在可以使用索引了

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)
我不知道你想用
逻辑做什么,所以我跳过了


代码-偏移量为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()
将值从上一行/下一行移到同一行,但移到新列。但是有了新的信息,我认为它会创建太多的新列,所以我删除了它


我想知道是否可以通过
滚动(window=3)
来完成,但我无法创建解决方案



博士:,

我找到了最终的解决方案。 解决问题的子问题:

代码:


为什么detection和ground_truth从4元素列表截断为2元素列表?因为值为1的元素被合并/挤压。这就是问题的确切任务,当检测是例如
[1,0,0,1,1,0]
时,它的行为如何?我不确定,但在熊猫中,您可以使用大小为3的
rolling()
,两个用于具有3个元素的滚动窗口,然后在运行某些代码之前,您必须检查中间元素是否为
1
。最后,您必须在
中使用slice
[i:i+3]
,用于使用
范围(len(…)
循环中,您可以使用
shift(1)
shift(-1)
若要将上一行和下一行的值放在新列中,但放在同一行中,然后您可以处理行中的数据,这两种解决方案仅适用于完全相同的列表,目标是找到一种方法来对任意长度的列表和任意索引的列表执行此操作。偏移量也是可变的!你可以一开始就写。您可以创建不同大小的示例数据。创建更多的示例以更好地描述问题。至于偏移量
[i:i+(2*offset)+1]
,我认为如果有更多的
1
,两个版本都可以给出更多的结果,所以唯一的问题是列表的大小。但可能
min(len(detection),len(ground_truth))
可以解决这个问题。如果您想单独使用列表,那么第一个代码应该只在第一个列表中找到
1
的索引,然后将此索引用于列表。我仍然不明白您在
逻辑中使用了哪些元素。是的,确切地说,找到
1
标识是第一项任务!偏移量定义了这些独立性的新范围,这些值应挤压/组合到
检测
列表中的
1
,相同的独立性范围应与地面真相列表中的逻辑
组合感谢您的努力。但是列表的长度总是相同的,只有这两个列表的长度是可变的。也许背景信息会有所帮助:它是基本事实,是对二进制时间序列分类的检测,因此1和0是机器学习模型的“真”/“假”结果。
   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]
# 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()