在 Python 中创建一组向量的笛卡尔积?
Creating the Cartesian Product of a set of Vectors in Python?
给定 3 维的标准基向量 (e_1,e_2,e_3)
并限制 (e_1,e_2,e_3)
的元素,比如 (0,1,2,3,4)
是否有一种简单的 pythonic 方法来创建笛卡尔积此向量中的所有向量 space?
例如,给定 [1,0,0]、[0,1,0] 和 [0,0,1],我想获得所有线性组合的列表(其中 a_i 仅限于 [0,0,0] 和 [4,4,4] 之间的这些向量的 0 和 4) 之间的自然数。
我可以自己编写程序,但在解决这个问题之前,我想我会问一下是否有一种简单的 pythonic 方法来实现它,也许是在 numpy 或类似的东西中。
编辑:这个答案有效,但我认为埃里克的更好,因为它更容易概括。
为了帮助可能偶然发现此问题的其他人。这是解决上述问题的一种非常简单的方法。它使用 np.where 来查找满足特定条件的矩阵的所有索引。在这里,我们的标准只是所有矩阵都满足的条件。这相当于上面的问题。这仅适用于上述示例,但将其推广到 N 维应该不会太困难。
import numpy as np
dim=3
gran=5
def vec_powerset(dim, gran):
#returns a list of all the vectors for a three dimensional vector space
#where the elements of the vectors are the naturals up to gran
size=tuple([gran]*dim)
a=np.zeros(size)
return [[np.where(a>(-np.inf))[0][x],np.where(a>(-np.inf))[1][x],
np.where(a>(-np.inf))[2][x]] for x in
range(len(np.where(a>(-np.inf))[0]))]
print vec_powerset(dim,gran)
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [0, 3, 4], [0, 4, 0], [0, 4, 1], [0, 4, 2], [0, 4, 3], [0, 4, 4], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 0], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 0], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 0, 3], [2, 0, 4], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 0], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 0], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 0], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 0, 0], [3, 0, 1], [3, 0, 2], [3, 0, 3], [3, 0, 4], [3, 1, 0], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 0], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 0], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 0], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 0, 0], [4, 0, 1], [4, 0, 2], [4, 0, 3], [4, 0, 4], [4, 1, 0], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 0], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 0], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 0], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]
对于 space 个自然数的特定情况,您需要 np.indices
:
>>> np.indices((4, 4)).reshape(2,-1).T
array([[0, 0],
[0, 1],
[0, 2],
[0, 3],
[1, 0],
[1, 1],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[2, 2],
[2, 3],
[3, 0],
[3, 1],
[3, 2],
[3, 3]])
(numpy 实际上在网格中输出这些,但你想要一个一维点列表,因此 .reshape
)
否则,您描述的不是幂集而是笛卡尔积
itertools.product(range(4), repeat=3)
给定 3 维的标准基向量 (e_1,e_2,e_3)
并限制 (e_1,e_2,e_3)
的元素,比如 (0,1,2,3,4)
是否有一种简单的 pythonic 方法来创建笛卡尔积此向量中的所有向量 space?
例如,给定 [1,0,0]、[0,1,0] 和 [0,0,1],我想获得所有线性组合的列表(其中 a_i 仅限于 [0,0,0] 和 [4,4,4] 之间的这些向量的 0 和 4) 之间的自然数。
我可以自己编写程序,但在解决这个问题之前,我想我会问一下是否有一种简单的 pythonic 方法来实现它,也许是在 numpy 或类似的东西中。
编辑:这个答案有效,但我认为埃里克的更好,因为它更容易概括。
为了帮助可能偶然发现此问题的其他人。这是解决上述问题的一种非常简单的方法。它使用 np.where 来查找满足特定条件的矩阵的所有索引。在这里,我们的标准只是所有矩阵都满足的条件。这相当于上面的问题。这仅适用于上述示例,但将其推广到 N 维应该不会太困难。
import numpy as np
dim=3
gran=5
def vec_powerset(dim, gran):
#returns a list of all the vectors for a three dimensional vector space
#where the elements of the vectors are the naturals up to gran
size=tuple([gran]*dim)
a=np.zeros(size)
return [[np.where(a>(-np.inf))[0][x],np.where(a>(-np.inf))[1][x],
np.where(a>(-np.inf))[2][x]] for x in
range(len(np.where(a>(-np.inf))[0]))]
print vec_powerset(dim,gran)
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 2, 4], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [0, 3, 4], [0, 4, 0], [0, 4, 1], [0, 4, 2], [0, 4, 3], [0, 4, 4], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 0, 4], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 3, 0], [1, 3, 1], [1, 3, 2], [1, 3, 3], [1, 3, 4], [1, 4, 0], [1, 4, 1], [1, 4, 2], [1, 4, 3], [1, 4, 4], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 0, 3], [2, 0, 4], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 1, 4], [2, 2, 0], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 3, 0], [2, 3, 1], [2, 3, 2], [2, 3, 3], [2, 3, 4], [2, 4, 0], [2, 4, 1], [2, 4, 2], [2, 4, 3], [2, 4, 4], [3, 0, 0], [3, 0, 1], [3, 0, 2], [3, 0, 3], [3, 0, 4], [3, 1, 0], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 1, 4], [3, 2, 0], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 2, 4], [3, 3, 0], [3, 3, 1], [3, 3, 2], [3, 3, 3], [3, 3, 4], [3, 4, 0], [3, 4, 1], [3, 4, 2], [3, 4, 3], [3, 4, 4], [4, 0, 0], [4, 0, 1], [4, 0, 2], [4, 0, 3], [4, 0, 4], [4, 1, 0], [4, 1, 1], [4, 1, 2], [4, 1, 3], [4, 1, 4], [4, 2, 0], [4, 2, 1], [4, 2, 2], [4, 2, 3], [4, 2, 4], [4, 3, 0], [4, 3, 1], [4, 3, 2], [4, 3, 3], [4, 3, 4], [4, 4, 0], [4, 4, 1], [4, 4, 2], [4, 4, 3], [4, 4, 4]]
对于 space 个自然数的特定情况,您需要 np.indices
:
>>> np.indices((4, 4)).reshape(2,-1).T
array([[0, 0],
[0, 1],
[0, 2],
[0, 3],
[1, 0],
[1, 1],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[2, 2],
[2, 3],
[3, 0],
[3, 1],
[3, 2],
[3, 3]])
(numpy 实际上在网格中输出这些,但你想要一个一维点列表,因此 .reshape
)
否则,您描述的不是幂集而是笛卡尔积
itertools.product(range(4), repeat=3)