python - 如何向量化此操作

标签 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]

在按元素比较这些列表时,我需要应用以下交集和并集规则:

# 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 labeling of text chunks ),其中每个列表元素是文档中的字符索引,而 vakue 是分配的枚举标签。 0代表一个标签代表没有注释(即,用于确定混淆矩阵中的负数);而非零元素表示为该字符分配的枚举标签。由于我忽略了真正的否定,我想我可以说 8 等同于 [0, 8]。至于这是否简化了事情,我还不确定。

* 编辑 2 *

我使用 [0, 8] 是为了让事情变得简单,并使 intersectionunion 的定义与集合论保持一致.

最佳答案

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

然而,做你想做的:

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)

这对于数千甚至数百万个元素来说绰绰有余,因为操作非常基础。当然,如果我们谈论的是数十亿,您可能还是想看看 numpy。

关于python - 如何向量化此操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57847157/

相关文章:

python - 如何在 Python 中进行 PGP(生成 key 、加密/解密)

python - 在另一个线程中与另一个 TCP 服务器一起使用 Flask

python - Python 中 R 的 "phyper"函数有哪些等价物?

python - 编辑 Python 绘图表面刻度及其频率

python - 如何使用 opencv 在 python 中的图像上制作自由手形(随机)

python - NumPy 标量、广播和 __iadd__ 方法

pandas - 将 Pandas 系列作为行有效地添加到现有数据帧

python - 如何矢量化 Pandas 操作以提高速度?

matlab - 通过用一个 2D 矩阵索引另一个 2D 矩阵来矢量化创建 3D 矩阵

r - 更有效的 which() 或 match() 策略