生成数组数组花费的时间太长

时间:2019-06-06 08:44:37

标签: python numpy

我正在尝试生成形式为所有可能的数组的数组

[x,y,z,(n-x-y-z),-20*x+0*y+-70*z+-20*(n-x-y-z)]

对于给定的n,其中xyz是整数。

它可以正确执行此操作,但是n=20大约需要2.3秒,而n=100似乎要花很多时间。

我知道这个数组的长度随着n的增加而增加。

我的理解是numpy可能允许更有效地创建这样的列表,但是我是Python的新手。关于如何更有效地执行此任务的任何建议?

def total_outcomes(n):
  return [[x,y,z,(n-x-y-z),-20*x+0*y+-70*z+-20*(n-x-y-z)] for x in range(0,n+1) for y in range(0,n-x+1) for z in range(0,n-x-y+1)]

1 个答案:

答案 0 :(得分:0)

如果我理解正确,则希望迭代x,y和z的组合,以使它们的总和不大于n。如果是这样,您可以创建从0到n的x,y和z的所有组合,然后创建一个布尔掩码,告诉它们的总和是否不大于n并提取正确的组合。检查这是否是您想要的:

import numpy as np

def total_outcomes(n):
    x = np.arange(n+1)
    y = np.arange(n+1)
    z = np.arange(n+1)
    xyz_combinations = np.array(np.meshgrid(x, y, z)).T.reshape(-1,3)
    sums = np.sum(xyz_combinations, axis=1)
    mask = sums <= n
    xyz_combinations = xyz_combinations[mask]
    x = (xyz_combinations[:,0]).reshape(-1,1)
    y = (xyz_combinations[:,1]).reshape(-1,1)
    z = (xyz_combinations[:,2]).reshape(-1,1)
    c4 = (n-x-y-z).reshape(-1,1)
    #c5 = value_argmaxrcev_bias_scrutiny(n)*x+value_argmaxrcev_bias_noscrutiny(n)*y+value_argmaxrcev_nobias_scrutiny(n)*z+value_argmaxrcev_nobias_noscrutiny(n)*(c4)
    c5 = ((-20)*x+0*y+(-70)*z+(-20)*(c4)).reshape(-1,1)
    return np.hstack((x,y,z,c4,c5))

运行速度非常快;在我的情况下,n = 100的计算立即完成。但是,计算时间也增长很快。当n = 1000时,它会停留约100秒。正如评论中提到的那样,您将无法克服此任务的计算复杂性。将问题强制转换为numpy实际上只会使计算进入较低级别(因为numpy用C编写并用python包装),因此比在python中循环要快。

对于n = 5,该代码生成:

array([[   0,    0,    0,    5, -100],
       [   0,    1,    0,    4,  -80],
       [   0,    2,    0,    3,  -60],
       [   0,    3,    0,    2,  -40],
       [   0,    4,    0,    1,  -20],
       [   0,    5,    0,    0,    0],
       [   1,    0,    0,    4, -100],
       [   1,    1,    0,    3,  -80],
       [   1,    2,    0,    2,  -60],
       [   1,    3,    0,    1,  -40],
       [   1,    4,    0,    0,  -20],
       [   2,    0,    0,    3, -100],
       [   2,    1,    0,    2,  -80],
       [   2,    2,    0,    1,  -60],
       [   2,    3,    0,    0,  -40],
       [   3,    0,    0,    2, -100],
       [   3,    1,    0,    1,  -80],
       [   3,    2,    0,    0,  -60],
       [   4,    0,    0,    1, -100],
       [   4,    1,    0,    0,  -80],
       [   5,    0,    0,    0, -100],
       [   0,    0,    1,    4, -150],
       [   0,    1,    1,    3, -130],
       [   0,    2,    1,    2, -110],
       [   0,    3,    1,    1,  -90],
       [   0,    4,    1,    0,  -70],
       [   1,    0,    1,    3, -150],
       [   1,    1,    1,    2, -130],
       [   1,    2,    1,    1, -110],
       [   1,    3,    1,    0,  -90],
       [   2,    0,    1,    2, -150],
       [   2,    1,    1,    1, -130],
       [   2,    2,    1,    0, -110],
       [   3,    0,    1,    1, -150],
       [   3,    1,    1,    0, -130],
       [   4,    0,    1,    0, -150],
       [   0,    0,    2,    3, -200],
       [   0,    1,    2,    2, -180],
       [   0,    2,    2,    1, -160],
       [   0,    3,    2,    0, -140],
       [   1,    0,    2,    2, -200],
       [   1,    1,    2,    1, -180],
       [   1,    2,    2,    0, -160],
       [   2,    0,    2,    1, -200],
       [   2,    1,    2,    0, -180],
       [   3,    0,    2,    0, -200],
       [   0,    0,    3,    2, -250],
       [   0,    1,    3,    1, -230],
       [   0,    2,    3,    0, -210],
       [   1,    0,    3,    1, -250],
       [   1,    1,    3,    0, -230],
       [   2,    0,    3,    0, -250],
       [   0,    0,    4,    1, -300],
       [   0,    1,    4,    0, -280],
       [   1,    0,    4,    0, -300],
       [   0,    0,    5,    0, -350]])