【问题标题】:Creating the Cartesian Product of a set of Vectors in Python?在 Python 中创建一组向量的笛卡尔积?
【发布时间】:2015-05-19 19:42:08
【问题描述】:

给定 3 维的标准基向量 (e_1,e_2,e_3) 并让 (e_1,e_2,e_3) 的元素被限制为,比如 (0,1,2,3,4) 是否有一种简单的 Pythonic 方法来创建该向量空间中所有向量的笛卡尔积?

例如,给定 [1,0,0],[0,1,0] 和 [0,0,1],我想获得所有线性组合的列表(其中 a_i 受到限制到 [0,0,0] 和 [4,4,4] 之间的这些向量的 0 和 4) 之间的自然数。

我可以自己编程,但在遇到麻烦之前,我想我会问是否有一种简单的 pythonic 方式来做这件事,也许是在 numpy 或类似的东西中。

【问题讨论】:

  • 最好的方法是“去[...]解决那个麻烦”并学习一些东西。如果遇到任何问题,请回来。如果你解决了你的问题,你很好。不满意的话,去codereview.stackexchange.com
  • @septi 感谢您的回复,但我也想看看是否有任何内置函数可以做到这一点。我发现在尝试做一些在我看来像是重新发明轮子的事情之前,四处询问并获得想法会有所帮助。此外,由于这对我来说似乎相当普遍,我认为这可能会帮助未来可能偶然发现这一点的其他人。我认为这是一个完全有效的问题。抱歉,如果您不这么认为。
  • 我很确定对于这个特定问题没有现成的功能。但是,正如您所发现的,itertoolsnumpy 非常适合向量和矩阵。所以学习如何使用它们,我相信你会找到一个很好的解决方案。
  • 听起来你只是想要itertools.product((0,1,2,3,4), repeat=3)。您描述的是笛卡尔积,而不是幂集
  • 我认为更接近stackoverflow.com/q/1208118/102441,因为numpy的区别很重要

标签: python numpy vector powerset


【解决方案1】:

对于自然数空间的特定情况,您需要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)

【讨论】:

    【解决方案2】:

    编辑:这个答案有效,但我认为 Eric 的更好,因为它更容易推广。

    为了帮助可能偶然发现此问题的其他人。这是解决上述问题的一种非常简单的方法。它使用 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]]
    

    【讨论】:

    • 你需要停止使用“powerset”这个词。它绘制了错误的搜索结果。
    • 如果你给我一个更好的术语,我很乐意编辑。我知道这是不正确的,但我想不出更好的说法。同时,我已将标题放在引号中
    • 您正在形成笛卡尔积。 en.wikipedia.org/wiki/Cartesian_product
    猜你喜欢
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2019-04-20
    • 2012-05-07
    • 2015-06-03
    • 2020-06-01
    • 2015-04-16
    • 2021-11-19
    相关资源
    最近更新 更多