如何向量化此操作

hor*_*uzz 5 python numpy vectorization

假设我有两个列表(长度相同):

l0 = [0, 4, 4, 4, 0, 0, 0, 8, 8, 0] 
l1 = [0, 1, 1, 1, 0, 0, 0, 8, 8, 8]
Run Code Online (Sandbox Code Playgroud)

在对这些列表进行逐元素比较时,我有以下关于交集和并集的规则:

# 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]]
Run Code Online (Sandbox Code Playgroud)

因此,所需的输出为:

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]
Run Code Online (Sandbox Code Playgroud)

在执行此操作的同时,我需要使用数百个非常大的列表(每个列表都包含数千个元素)来执行此操作,因此我正在寻找一种矢量化方法。我尝试使用np.where和各种屏蔽策略,但是进展很快。任何建议将是最欢迎的。

*编辑*

关于

uni: [0, [4, 1], [4, 1], [4, 1], 0, 0, 0, 8, 8, 8]
Run Code Online (Sandbox Code Playgroud)

uni: [0, [4, 1], [4, 1], [4, 1], 0, 0, 0, 8, 8, [0, 8]]
Run Code Online (Sandbox Code Playgroud)

我仍在思考8与[0,8]的对抗。列表是从系统注释中的BIO标记派生的(请参阅IOB文本块标签),其中每个列表元素是文档中的字符索引,而vakue是分配的枚举标签。0表示不注释的标签(即,用于确定混淆矩阵中的否定标签);非零元素代表为该字符分配的枚举标签。由于我忽略了真正的负面因素,因此我想我可以说8等于[0,8]。至于这是否简化事情,我还不确定。

*编辑2 *

[0, 8]用来使事情保持简单,并保持集合论的定义intersectionunion与之保持一致。

Gri*_*mar 2

我不会将它们称为“交集”和“并集”,因为这些操作在集合上具有明确定义的含义,而您要执行的操作都不是它们。

但是,要做你想做的事:

l0 = [0, 4, 4, 4, 0, 0, 0, 8, 8, 0]
l1 = [0, 1, 1, 1, 0, 0, 0, 8, 8, 8]

values = [
    (x
     if x == y else 0,
     0
     if x == y == 0
     else x if y == 0
     else y if x == 0
     else [x, y]) 
    for x, y in zip(l0, l1)
]

result_a, result_b = map(list, zip(*values))

print(result_a)
print(result_b)
Run Code Online (Sandbox Code Playgroud)

由于操作非常基础,这对于数千甚至数百万个元素来说已经足够了。当然,如果我们谈论的是数十亿,您可能无论如何都想看看 numpy。