通过python在列表中找到不同的对

vin*_*lai 14 python performance numpy

我有一个列表,我想在列表中找到不同的对.我实现了一个函数 - > different()

import numpy as np


def different(array):
    res = []
    for (x1, y1), (x2, y2) in array:
        if (x1, y1) != (x2, y2):
            res.append([(x1, y1), (x2, y2)])
    return res


a = np.array([[[1, 2], [3, 4]],
              [[1, 2], [1, 2]],
              [[7, 9], [6, 3]],
              [[3, 3], [3, 3]]])

out = different(a)  # get [[(1, 2), (3, 4)],
                    #      [(7, 9), (6, 3)]]
Run Code Online (Sandbox Code Playgroud)

还有其他更好的方法吗?我想提高我的功能不同.列表大小可能大于100,000.

Joe*_*Joe 8

这种笨拙的方式是

import numpy as np

a = np.array([[[1, 2], [3, 4]],
              [[1, 2], [1, 2]],
              [[7, 9], [6, 3]],
              [[3, 3], [3, 3]]])

b = np.logical_or(a[:,0,0] != a[:,1,0],  a[:,0,1] != a[:,1,1])

print(a[b])
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案未能将"[[1,2],[1,3]]"识别为不同,而OP则标记它. (3认同)

cs9*_*s95 6

矢量化比较

a[~(a[:, 0] == a[:, 1]).all(1)]

array([[[1, 2],
        [3, 4]],

       [[7, 9],
        [6, 3]]])
Run Code Online (Sandbox Code Playgroud)

这是通过获取每个子阵列的第一对并将每个子阵列与第二对子阵列进行比较来实现的.选择不相同的条目的所有子阵列.考虑,

a[:, 0] == a[:, 1]

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

从这里,我们希望每列中没有True的那些行.因此,在此结果上,使用all然后否定结果.

~(a[:, 0] == a[:, 1]).all(1)
array([ True, False,  True, False])
Run Code Online (Sandbox Code Playgroud)

这为您提供了一个掩码,然后您可以使用它来从中选择子阵列a.


np.logical_or.reduce

与上面的第一个选项类似,但从另一端接近这个问题(参见DeMorgan定律).

a[np.logical_or.reduce(a[:, 0] != a[:, 1], axis=1)]
Run Code Online (Sandbox Code Playgroud)