热得到两个 2d numpy 数组的集合差异,或等效于 2d 数组中的 np.setdiff1d?

Hot to get the set difference of two 2d numpy arrays, or equivalent of np.setdiff1d in a 2d array?

这里 Get intersecting rows across two 2D numpy arrays 他们使用函数 np.intersect1d 得到了相交的行。所以我将函数更改为使用 np.setdiff1d 来获取设置差异,但它无法正常工作。以下是代码。

def set_diff2d(A, B):
    nrows, ncols = A.shape
    dtype={'names':['f{}'.format(i) for i in range(ncols)],
          'formats':ncols * [A.dtype]}
    C = np.setdiff1d(A.view(dtype), B.view(dtype))

    return C.view(A.dtype).reshape(-1, ncols)

以下数据用于检查问题:

min_dis=400
Xt = np.arange(50, 3950, min_dis)
Yt = np.arange(50, 3950, min_dis)

Xt, Yt = np.meshgrid(Xt, Yt)
Xt[::2] += min_dis/2
# This is the super set
turbs_possible_locs = np.vstack([Xt.flatten(), Yt.flatten()]).T
# This is the subset
subset = turbs_possible_locs[np.random.choice(turbs_possible_locs.shape[0],50, replace=False)]
diffs = set_diff2d(turbs_possible_locs, subset)

diffs 应该是 50x2 的形状,但实际上不是。

好的,要解决您的问题,请尝试以下调整:

def set_diff2d(A, B):
    nrows, ncols = A.shape
    dtype={'names':['f{}'.format(i) for i in range(ncols)], 'formats':ncols * [A.dtype]}
    C = np.setdiff1d(A.copy().view(dtype), B.copy().view(dtype))
    return C

问题是 - A 在应用 .view(...) 后被分成两半 - 所以它有 2 tuple 列,而不是像 B 那样的 1 列。 IE。作为应用 dtype 的结果,你基本上将 2 列折叠成 tuple - 这就是为什么你可以首先在 1d 中进行交集。

文档后引用:

"

a.view(some_dtype) 或 a.view(dtype=some_dtype) 用不同的 data-type 构造数组内存的视图。这可能导致重新解释内存字节。

"

源码https://numpy.org/doc/stable/reference/generated/numpy.ndarray.view.html

我认为“重新解释”正是发生的事情 - 因此为了简单起见,我只 .copy() 数组。

NB 但是我不会平方它 - 它总是 A 得到 'broken' - 无论是赋值还是内联 B总是好的...