【问题标题】:The set of all combinations of vectors in PythonPython中所有向量组合的集合
【发布时间】:2013-09-05 10:40:44
【问题描述】:

我在创建可以看作是 Python 中向量数组的笛卡尔积的问题时遇到了问题。我有一个代码,它给出了数字 n 在 r 变量上的所有可能分区,并将其作为 numpy 数组返回。我想做的是能够任意调用该代码,然后生成一组所有可能的数组组合。

举个例子,我可能会调用分区代码和每个连续的调用(针对不同的参数集)

array([[2,0],[1,1],[2,0]])
array([[1,0],[0,1]])
array([[0,0]])

我正在寻找的是能够返回集合

array([[2,0],[1,0],[0,0]])
array([[2,0],[0,1],[0,0]])
array([[1,1],[1,0],[0,0]])
.....

要么作为一个整体数组,要么逐行返回(由于随着被分区数量的增长而出现明显的内存问题)。

之前我使用 itertools.product 解决了这个问题,并在 PyPy 下运行代码。但是,由于项目的其他部分需要 Numpy,我不得不从 PyPy 切换到标准 python,并且我试图通过使用 Numpy 来复制 PyPy 代码的速度。我已经设法让这个工作非常粗略,但是代码花了很多时间在数据类型之间进行更改,以便尝试一起引导一个解决方案,这对于实现来说是不切实际的。

我想知道是否有人能够帮助我提供一些指导,告诉我应该如何在 Python 中取得进展。

谢谢

【问题讨论】:

  • 您是否正在使用 numpy 命令构建外部产品?可以提供代码吗?
  • 你的意思是生成数组的分区代码([[2,0],[1,1],[2,0]]) array([[1,0],[0 ,1]]) 数组([[0,0]])

标签: python math numpy cartesian


【解决方案1】:

这应该让你开始:

import numpy as np
import itertools as it

def row_product(*arrays):
    lengths = np.array([x.shape[0] for x in arrays])
    positions = np.cumsum(lengths)

    ranges = np.arange(positions[-1])
    ranges = np.split(ranges,positions[:-1])

    total = np.concatenate((arrays),axis=0)

    inds = np.fromiter(it.chain.from_iterable(it.product(*ranges)), np.int)
    inds = inds.reshape(-1, len(arrays))

    return np.take(total, inds, axis=0)

最后一个维度必须相同。

显示结果:

a=np.array([[2,0],[1,1],[2,0]])
b=np.array([[1,0],[0,1]])
c=np.array([[0,0]])

print row_product(a,b,c)

[[[2 0]
  [1 0]
  [0 0]]

 [[2 0]
  [0 1]
  [0 0]]

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

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

 [[2 0]
  [1 0]
  [0 0]]

 [[2 0]
  [0 1]
  [0 0]]]

这是一个 3D 数组,其中唯一的组合位于最后两个轴上。似乎相当快,1M 独特组合大约需要 1/6 秒。

【讨论】:

  • 谢谢你!但是,我一直遇到的一个问题是如何为任意一组输入参数调用它。例如,我尝试调用 row_product([compositions(i,2) for i in xrange(4)]) 或 row_product(row_product(a,b),c),但这些似乎都不是可调用的。这可能是一个愚蠢的问题,但是将 n 个数组传递给 row_product 的最佳方法是什么?
  • 如果要将容器传递给row_product,请将row_product(*arrays) 更改为row_product(arrays) 并将np.concatenate((arrays),axis=0) 更改为np.concatenate(arrays,axis=0)
  • 非常感谢您对这个 Ophion 的帮助。几个星期以来,我一直在处理这个问题(或包含此问题的更大问题),非常感谢您花时间解决这个问题。
  • 如果此答案提供了您想要的信息,请考虑接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多