Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在numpy中高效地生成所有可能的坐标对而不重复_Python_Arrays_Numpy_Combinations - Fatal编程技术网

Python 如何在numpy中高效地生成所有可能的坐标对而不重复

Python 如何在numpy中高效地生成所有可能的坐标对而不重复,python,arrays,numpy,combinations,Python,Arrays,Numpy,Combinations,我正在尝试为带有颜色的图像中的像素生成所有坐标对,而不重复这些坐标对(顺序不重要,因此((1,1,1),(2,2,2)与((2,2,2),(1,1,1))相同,我们只希望包含这一对)。此外,坐标存储在numpy数组中对我来说很重要 假设我有一个10x10的图像。这意味着图像有100个像素,有3个颜色通道,相当于300个坐标。这给了我们300*299/2个唯一的坐标对。使用itertools.combines()或普通python迭代,然后转换为np.array,对于较大的图像来说,速度非常慢(在

我正在尝试为带有颜色的图像中的像素生成所有坐标对,而不重复这些坐标对(顺序不重要,因此((1,1,1),(2,2,2)与((2,2,2),(1,1,1))相同,我们只希望包含这一对)。此外,坐标存储在numpy数组中对我来说很重要

假设我有一个10x10的图像。这意味着图像有100个像素,有3个颜色通道,相当于300个坐标。这给了我们300*299/2个唯一的坐标对。使用
itertools.combines()
或普通python迭代,然后转换为np.array,对于较大的图像来说,速度非常慢(在我的电脑上,32x32x3图像需要5秒钟)

我能够使用创建所有像素的列表

all_pixels=np.array(np.meshgrid(范围(10)、范围(10)、范围(3))).T.重塑(-1,3)

但这是因为我们不必考虑重复。这样做,但试图创建一对像素给了我重复。我想我可以删除一些重复的一些聪明的方式,但我不知道如何以有效的方式来做。< /P> 任何帮助都将不胜感激

这有点粗糙,但作为参考,我现在是这样做的:

    start = time.time()
    x, y, z = shape
    all_pixels = []
    for i in range(x):
        for j in range(y):
            if z > 1:
                for k in range(z):
                    all_pixels.append([i, j, k])
            else:
                all_pixels.append([i, j])
    first_pix = []
    second_pix = []
    for i in range(len(all_pixels)):
        first = all_pixels[i]
        for j in all_pixels[i+1:]:
            second = j
            first_pix.append(first)
            second_pix.append(second)
    print("generation of pixels took " + str(time.time() - start))
    return np.array(first_pix), np.array(second_pix)
以下示例比OP的解决方案更酷但速度较慢:( 每个回路3.57 ms±59.7µs(7次运行的平均值±标准偏差,每个100个回路) ​

每个回路36.5 ms±1.33 ms(7次运行的平均值±标准偏差,每个10个回路)

代码 创建一个所有像素的列表,但是我们使用元组,所以它们是可散列的。我们稍后会看到原因

img_width = 10
img_height = 10
img_colors = 3

pixels = [(x, y, c) for x in range(img_width) for y in range(img_height) for c in range(3)]
现在我们使用集合来确保没有重复项

mixed = {frozenset((i, j)) for i in pixels for j in pixels if i != j}
现在,我们检查它是否具有正确数量的值:

>>> desired_length = (len(pixels) * (len(pixels) - 1)) / 2
>>> assert len(mixed) == desired_length
True
解释 我们使用二维集合理解来创建置换。其格式如下:

{(x, y) for x in xs for y in ys}
因为这是一个集合集合中的所有项都是唯一的。这要求集合中的所有项都是可散列的,即python中的每个项都是可比较的

因为我们不仅希望像素组合是唯一的,我们还希望它们是顺序独立唯一的。因此,我们再次使用一个集合,但由于正常集合是不可散列的,我们使用内部类型冻结集。它现在实际上是一个元组的集合。它是可散列和顺序独立的登登

>>> frozenset([(0, 0, 1), (0, 0 , 2)]) == frozenset([(0, 0, 2), (0, 0 , 1)])
True
我们必须添加
i!=j
以确保不会在冻结集中输入两次相同的坐标,从而导致长度为1的结果。(例如
set([(0,0,1),(0,0,1)])
等于
{(0,0,1)}

完整代码 每个回路38.2 ms±2.46 ms(7次运行的平均值±标准偏差,每个10个回路)


下面是一个简单的numpy方法,不确定它有多快:

shape = 10,10,3
np.stack([*map(np.transpose, map(np.unravel_index, np.triu_indices(np.prod(shape),1), 2*(shape,)))],-2)
输出:

array([[[0, 0, 0],
        [0, 0, 1]],

       [[0, 0, 0],
        [0, 0, 2]],

       [[0, 0, 0],
        [0, 1, 0]],

       ...,

       [[9, 9, 0],
        [9, 9, 1]],

       [[9, 9, 0],
        [9, 9, 2]],

       [[9, 9, 1],
        [9, 9, 2]]])
更新:相同的想法,相同的结果,但更快

np.column_stack(np.unravel_index(np.arange(np.prod(shape)),shape))[np.column_stack(np.triu_indices(np.prod(shape),1))]

.T.整形(-1,3)
@Divakar@Divakar我能够在Python3
all_pixels=np.array(np.meshgrid(range(10)、range(10)、range(3)))中运行它
Sackhorn,你真的需要将通道作为坐标的第三维度吗?我认为你可以在配对后考虑通道,因为通道的数量对于两幅图像的每个像素都是恒定的,而宽度和高度则不会。这将使你的问题更快,因为你要除以3坐标数。看起来可能不多,但创建对的值是O(n^2),如果要删除重复项,则为O(n^3),因此,将n除以3就像将复杂度除以27。将通道作为第三维度会很好,但我可以解决这一问题,因此它们不是必需的。您的代码工作正常,但问题是,普通python for循环和使用python集合生成所有对在我的pc上转换py大约需要5秒的时间(32x32x3)thon collection到np.array。您的方法大约需要9秒而无需转换。您确定吗?在我的笔记本电脑上,不是最先进的,每个循环的
35.7 ms±544µs(平均±标准偏差为7次运行,每个循环10次)
我的电脑也不太好。让我再检查一次。但我非常确定。我在问题中公布了我现在运行它的方式。你自己的方法实际上需要在我的笔记本电脑上使用
3 ms
。更新的答案反映了这一点,看起来很棒。让我检查你的答案,我会接受它。
%%timeit

img_width = 10
img_height = 10
img_colors = 3

pixels = [(x, y, c) for x in range(img_width) for y in range(img_height) for c in range(3)]
mixed = {frozenset((i, j)) for i in pixels for j in pixels if i != j}
shape = 10,10,3
np.stack([*map(np.transpose, map(np.unravel_index, np.triu_indices(np.prod(shape),1), 2*(shape,)))],-2)
array([[[0, 0, 0],
        [0, 0, 1]],

       [[0, 0, 0],
        [0, 0, 2]],

       [[0, 0, 0],
        [0, 1, 0]],

       ...,

       [[9, 9, 0],
        [9, 9, 1]],

       [[9, 9, 0],
        [9, 9, 2]],

       [[9, 9, 1],
        [9, 9, 2]]])
np.column_stack(np.unravel_index(np.arange(np.prod(shape)),shape))[np.column_stack(np.triu_indices(np.prod(shape),1))]