【问题标题】:Fast way to build array from originating arrays of different sizes从不同大小的原始数组构建数组的快速方法
【发布时间】:2019-08-21 21:15:00
【问题描述】:

我正在从两个大小为 (1000,100,100,100) 和 (100,100,100) 的数组构建一个 (1000,100,100,100) 数组。为此,我使用 for 循环来运行第一个条目 (0 - 1000)。但是,我的代码(如下)仍然很慢,作为初学者,我想知道是否有更有效的方法来做到这一点。

n_train = 1000
Nx = 100
Ny = 100
Nt = 100

x = np.linspace(-Nx, Nx, 100)
y = np.linspace(-Ny, Ny, 100)
t = np.linspace(0, Nt-1, 100)

def gw(xx, yy, tt):
    num1 = tt - np.sqrt(xx**2+yy**2)
    denom = (tt**2-xx**2-yy**2)

    if denom < 0:
        denom1 = 0
    else:
        denom1 = np.sqrt(denom)

    kk = np.heaviside(num1,1)/(2*np.pi*denom1+1)

return (kk)

# Slow FOR-LOOP
for i_train in range (n_train):

    ugreen = np.array([gw(i, j, k) for k in t for j in y for i in x])
    Ugreen = ugreen.reshape(Nt, Ny, Nx)

    prob = randrange(2)
    Utot = UN[i_train,:,:,:] + Ugreen/1.75*prob
    Utot = (Utot - np.min(Utot))/(np.max(Utot)-np.min(Utot))

    Utot_green = 10*Ugreen/1.75*prob


    P[i_train,:,:,:] = Utot
    Pg[i_train,:,:,:]= Utot_green

【问题讨论】:

  • 查看code review,它针对这样的优化问题
  • @C.Nivs,你在 CR 上回答过这样的问题吗?

标签: python arrays python-3.x numpy for-loop


【解决方案1】:

我认为有几个问题使这变得困难。首先,您的代码 sn-p 无法编译,恕我直言,这在任何编程语言和相应的论坛中都是有问题的。 其次,你没有解释你实际上试图用你的代码计算什么。所以我不得不将你的代码翻译回数学。 这让我想到了这个问题的特定于 numpy 的问题。

长话短说:如果你能给出某种关于向量和矩阵的数学方程,答案会容易得多。

randrange
UN
P
PG

未在您的代码中定义。

在每个循环中,您都会再次评估 Ugreen,但我没有看到它在您的循环中发生变化。将其移出循环并节省时间。

gw()

可以写成矢量化(现在很容易看到您正在计算的内容 - 这应该与您现在笔记中的手写方程式非常相似):

import numpy as np
from scipy import sqrt

def gw(xx,yy,tt):
    return (0<=tt-sqrt(xx**2+yy**2))/(2*np.pi*sqrt(np.clip(tt**2-xx**2-yy**2,0,None))+1)

Ugreen = gw(x[:,None,None],y[None,:,None],t[None,None,:])
prob = randrange(2)#I assume this is some scalar
Utot = UN + Ugreen[None,:,:,:]/1.75*prob
Utot = (Utot - np.min(Utot,axis=0)[None,...])/(np.max(Utot,axis=0)[None,...]-np.min(Utot,axis=0)[None,...]

这是我认为您正在尝试计算的工作示例

import numpy as np
from scipy import sqrt

def gw(x,y,t):
    return (0<=t-sqrt(x**2+y**2))/(2*np.pi*sqrt(np.clip(t**2-x**2-y**2,0,None))+1)

n_train = 1000
Nx = 100
Ny = 100
Nt = 100

x = np.linspace(-Nx, Nx, 100)
y = np.linspace(-Ny, Ny, 100)
t = np.arange(Nt)

Ugreen = gw(x[:,None,None],y[None,:,None],t[None,None,:])

prob = 2

Utot = np.random.random((n_train,Nt,Ny,Nx))
Utot += Ugreen[None,:,:,:]/1.75*prob
Utot /= (np.max(Utot,axis=0)[None,...]-np.min(Utot,axis=0)[None,...])
Utot -= np.min(Utot,axis=0)[None,...]/(np.max(Utot,axis=0)[None,...]-np.min(Utot,axis=0)[None,...])

我必须安排Utot-evaluation,以免遇到内存问题。 但是,在我的机器上它会在几秒钟内运行。 当然可以进一步优化这一点,我希望其他用户的一些回应可以学习新事物。

关于 numpy 的一些一般提示: 恕我直言,如果您想了解 numpy 的真正实用功能,最好忘记您对其他语言的数值编程所了解的一切,而不是坚持您可能拥有的任何想法/想法/循环思维。 我的经验是,是的,numpy 非常快,这非常好等等,但它也使您的代码非常短、紧凑,并且最适合科学工作:非常接近您可能想要解决的任何复杂方程。人们应该开始尽可能接近论文来实现方程,并且只在必要的地方和必要时进行优化。

【讨论】:

  • 非常感谢您的详细回答和您的努力。我是一个完整的初学者,这就是为什么我没有任何声誉来支持你的答案。但我非常感谢您在解决我的问题时的耐心和支持。再次感谢。
猜你喜欢
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
  • 1970-01-01
  • 2018-12-31
  • 2018-09-29
  • 1970-01-01
  • 2019-03-21
相关资源
最近更新 更多