检查 numpy 数组是否是另一个数组的子集

aes*_*vex 6 python numpy set

类似的问题已经被问到了,但他们有更具体的限制,他们的答案不适用于我的问题。

一般来说,确定任意 numpy 数组是否是另一个数组的子集的最 Pythonic 方法是什么?更具体地说,我有一个大约 20000x3 的数组,我需要知道完全包含在集合中的 1x3 元素的索引。更一般地说,是否有一种更Pythonic的方式来编写以下内容:

master = [12, 155, 179, 234, 670, 981, 1054, 1209, 1526, 1667, 1853]  # some indices of interest
triangles = np.random.randint(2000, size=(20000, 3))  # some data

for i, x in enumerate(triangles):
    if x[0] in master and x[1] in master and x[2] in master:
        print i
Run Code Online (Sandbox Code Playgroud)

对于我的用例,我可以安全地假设 len(master) << 20000。(因此,也可以安全地假设 master 已排序,因为这很便宜)。

pet*_*hor 4

您可以通过在列表理解中迭代数组来轻松完成此操作。一个玩具示例如下:

import numpy as np
x = np.arange(30).reshape(10,3)
searchKey = [4,5,8]
x[[0,3,7],:] = searchKey
x
Run Code Online (Sandbox Code Playgroud)

给出

 array([[ 4,  5,  8],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 4,  5,  8],
        [12, 13, 14],
        [15, 16, 17],
        [18, 19, 20],
        [ 4,  5,  8],
        [24, 25, 26],
        [27, 28, 29]])
Run Code Online (Sandbox Code Playgroud)

现在迭代元素:

ismember = [row==searchKey for row in x.tolist()]
Run Code Online (Sandbox Code Playgroud)

结果是

[True, False, False, True, False, False, False, True, False, False]
Run Code Online (Sandbox Code Playgroud)

您可以将其修改为问题中的子集:

searchKey = [2,4,10,5,8,9]  # Add more elements for testing
setSearchKey = set(searchKey)
ismember = [setSearchKey.issuperset(row) for row in x.tolist()]
Run Code Online (Sandbox Code Playgroud)

如果您需要索引,请使用

np.where(ismember)[0]
Run Code Online (Sandbox Code Playgroud)

它给

array([0, 3, 7])
Run Code Online (Sandbox Code Playgroud)