如何创建一个二维数组,其中包含每列约束范围的所有可能组合

How to create a 2D array with all possible combinations of a constrained range for each column

我有三个范围,我想创建一个包含这些范围的所有可能组合的 3 列数组,并使其按特定顺序排列。我知道如何用循环来做到这一点。然而,实际上数据将超过 3 列并且范围非常大,所以我认为循环效率低下并且希望有一种快速的方法来执行此操作。实际数据集大小约为 5 GB,因此效率对我来说很关键。例如:

inc = 1
a = np.arange(1001,1002+inc,inc)
b = np.arange(1,3+inc,inc)
c = np.arange(1,5+inc,inc)

我想创建如下所示的输出:

array([[1001,    1,    1],
       [1001,    1,    2],
       [1001,    1,    3],
       [1001,    1,    4],
       [1001,    1,    5],
       [1001,    2,    1],
       [1001,    2,    2],
       [1001,    2,    3],
       [1001,    2,    4],
       [1001,    2,    5],
       [1001,    3,    1],
       [1001,    3,    2],
       [1001,    3,    3],
       [1001,    3,    4],
       [1001,    3,    5],
       [1002,    1,    1],
       [1002,    1,    2],
       [1002,    1,    3],

这个输出并不完整,但它显示了我想要的。我应该补充一点,我这样做是因为我有一个格式相同但缺少行的输入 table,我希望能够通过将输入数据集与此 'ideal' table。如上所述,我可以使用 for 循环来完成此操作,但如果可能的话,我想找到一种更符合 Pythonic 的方法。

您可以使用 built-in itertools.product:

轻松完成
import itertools as it

perms = np.array(list(it.product(a, b, c)))

输出:

>>> perms
array([[1001,    1,    1],
       [1001,    1,    2],
       [1001,    1,    3],
       [1001,    1,    4],
       [1001,    1,    5],
       [1001,    2,    1],
       [1001,    2,    2],
       [1001,    2,    3],
       [1001,    2,    4],
       [1001,    2,    5],
       [1001,    3,    1],
       [1001,    3,    2],
       [1001,    3,    3],
       [1001,    3,    4],
       [1001,    3,    5],
       [1002,    1,    1],
       [1002,    1,    2],
       [1002,    1,    3],
       [1002,    1,    4],
       [1002,    1,    5],
       [1002,    2,    1],
       [1002,    2,    2],
       [1002,    2,    3],
       [1002,    2,    4],
       [1002,    2,    5],
       [1002,    3,    1],
       [1002,    3,    2],
       [1002,    3,    3],
       [1002,    3,    4],
       [1002,    3,    5]])

我推荐使用 numpy.meshgrid,因为它运行得更快。

>>> np.array(np.meshgrid(a,b,c)).T.reshape((-1, 3))
array([[1001,    1,    1],
       [1001,    2,    1],
       [1001,    3,    1],
       [1002,    1,    1],
       [1002,    2,    1],
       [1002,    3,    1],
       [1001,    1,    2],
       [1001,    2,    2],
       [1001,    3,    2],
       [1002,    1,    2],

如果顺序很重要,这似乎可以做到。

np.array([m.flatten() for m in np.meshgrid(a,b,c, indexing='ij')]).T