【发布时间】:2020-01-10 19:35:09
【问题描述】:
假设我有两个列表(总是相同的长度):
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] 来保持简单,并使intersection 和union 的定义与集合论保持一致。
【问题讨论】:
-
矢量化交点很简单。
np.where(a0==l1,a0,0)wherea0 = np.array(l0).向量化你的uni会很困难,因为输出不是一个有效的numpy数组。它可能是,但它的dtype将是object,从而抵消了库中的大多数矢量化收益 -
uni中的列表和标量的混合很好地表明了完全“矢量化”的解决方案是不可能的。如果解决方案具有不同长度的列表(或数组),情况也是如此。 -
你能定义nowhere fast吗?您的解决方案现在拥有数百个大型列表的速度有多快?
-
呃,无处可逃的意思:我没办法!在速度方面没有任何意义。我有十字路口,但工会是症结所在。
标签: python numpy vectorization