【问题标题】:Vectorized relative complement of sets in numpynumpy中集合的向量化相对补集
【发布时间】:2021-10-09 17:04:28
【问题描述】:

我有 np.arange(n) A 和一个 numpy 数组 B 的非相交子数组 - 将初始数组划分为 k 个连续数字数组。
一个例子是:

A = [0, 1, 2, 3, 4, 5, 6]
B = [[0, 1], [2, 3, 4], [5, 6]]

对于 B 的每个子数组 C 我必须计算 A\C (其中 \ 是对集合的操作,因此结果是A 中所有不在 B 中的元素的 numpy 数组)。 我目前的解决方案达到了时间限制:

import numpy as np
for C in B:
    ans.append(np.setdiff1d(A, C))
return ans

我想通过使用矢量化来加速它,但我不知道怎么做。我试图移除循环,只留下 setxor1d 和 setdiff1d 之类的函数,但失败了。

【问题讨论】:

  • 这与 6 小时前的有什么不同? stackoverflow.com/q/69416426/901925
  • 我重写了这篇文章,只包含最小的可重现示例,因为这是评论者的建议之一

标签: python numpy optimization set vectorization


【解决方案1】:

我假设 A 和 B 的子数组已排序并且具有唯一元素。然后对于我下面的示例,将 10**6 个整数分为以下代码生成的 100 个子数组。

np.random.seed(0)
A = np.sort(np.unique(np.random.randint(0,10**10,10**6)))
B = np.split(A, np.sort(np.random.randint(0,10**6-1,99)))

您可以通过设置unique=True 将时间减半。并通过仅对位于 B 的特定子集中的最大和最小数字之间的 A 中的数字进行 setminus 将时间缩短 3 倍。我意识到我的示例是最佳情况优化以提供帮助,因此我不确定这对您的现实世界示例有何影响。你将不得不尝试。

boundaries = [x[i] for x in B for i in [0,-1]]
boundary_idx = np.searchsorted(A, boundaries).reshape(-1,2)
[np.concatenate([A[:x[0]], 
                 np.setdiff1d(A[x[0]:x[1]+1], b, assume_unique=True), 
                 A[x[1]+1:]])
         for b,x in zip(B, boundary_idx)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2017-05-04
    相关资源
    最近更新 更多