假设我有两个列表(长度始终相同):
l0 = [0, 4, 4, 4, 0, 0, 0, 8, 8, 0]
l1 = [0, 1, 1, 1, 0, 0, 0, 8, 8, 8]
我有以下关于交集和并集的规则,需要逐个元素地将这些列表进行比较:
# union and intersect
uni = [0]*len(l0)
intersec = [0]*len(l0)
for i in range(len(l0)):
if l0[i] == l1[i]:
uni[i] = l0[i]
intersec[i] = l0[i]
else:
intersec[i] = 0
if l0[i] == 0:
uni[i] = l1[i]
elif l1[i] == 0:
uni[i] = l0[i]
else:
uni[i] = [l0[i], l1[i]]
因此,所需的输出为:
uni: [0, [4, 1], [4, 1], [4, 1], 0, 0, 0, 8, 8, 8]
intersec: [0, 0, 0, 0, 0, 0, 0, 8, 8, 0]
虽然这样做是可行的,但我需要对几百个非常大的列表(每个列表都有数千个元素)进行此操作,因此我正在寻找一种向量化的方法。我尝试使用np.where
和各种掩码策略,但进展缓慢。欢迎提供建议。
*编辑*
关于
uni: [0, [4, 1], [4, 1], [4, 1], 0, 0, 0, 8, 8, 8]
对抗
uni: [0, [4, 1], [4, 1], [4, 1], 0, 0, 0, 8, 8, [0, 8]]
我仍在脑海中纠结于8与[0, 8]。这些列表源自系统注释中的BIO标记(请参见文本块的IOB标记),其中每个列表元素都是文档中的字符索引,其值是分配的枚举标签。0表示代表无注释的标签(即用于确定混淆矩阵中的负面因素);而非零元素表示该字符的分配枚举标签。由于我忽略了真正的负面因素,所以我认为8等同于[0, 8]。至于这是否简化了事情,我还不确定。
* 编辑2 *
我使用[0, 8]
来保持简单,并使intersection
和union
的定义与集合论一致。
np.where(a0==l1,a0,0)
,其中a0 = np.array(l0)
。向量化你的uni
将会很困难,因为输出不是一个有效的numpy
数组。它可能是,但它的dtype
将是object
,从而使大部分向量化收益失效。 - rafaelcuni
中列表和标量的混合是一个很好的指示,表明完全“向量化”的解决方案是不可能的。如果解决方案具有长度不同的列表(或数组),则同样适用。 - hpaulj