【问题标题】:The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()具有多个元素的数组的真值是不明确的。使用 a.any() 或 a.all()
【发布时间】:2015-09-16 13:52:42
【问题描述】:

虽然我知道有各种问题在寻找此错误消息的解决方案,但我还没有找到可以帮助我解决代码以进行比较的答案,我有代码

def f(x,d,h,L):
    ans=0.
    if ((0.<=x) & (x<d)):
        ans=h*(x/d)
    elif ((d<=x) & (x<=L)):
        ans=((L-x)/(L-d))
    return ans

x=np.linspace(0,10,1000)
h=5*10**(-3)
d=16*10**(-2)
L=64.52*10**(-2)
func=f(x,d,h,L)

但是当我尝试运行它时,我得到一个指向 if 行的错误,并且标题中有错误代码,我已经尝试了类似问题中给出的建议解决方案,例如改用 np.logical_andand&amp; 但所有三个都产生相同的错误,请帮助我

【问题讨论】:

  • x 是一个数组。如果x 中的任何一个/所有都在一个范围内,您是否希望f 做一件事,如果他们不这样做,则做不同的事情?或者您是否希望它对位于一个范围内的 x 值做一件事,而对其他 x 值做另一件事?换句话说,if 测试适用于整个x 还是适用于单个元素?
  • 另一种方式来提出我的问题 - 如果您将 x 的元素单独传递给它,该功能是否正常工作?

标签: python arrays numpy error-code


【解决方案1】:

使用 numpy.where。 (可选)对浮点数使用指数表示法。

import numpy as np

def f(x, d, h, L):
    return np.where(x < d, h*(x/d), (L - x)/(L - d))

x = np.linspace(0,10,1000)
h = 5e-3
d = 16e-2
L = 64.52e-2

func = f(x, d, h, L)

【讨论】:

    【解决方案2】:

    您关注的是从句的连词,但它是从句本身。你可能想要这样的东西:

    if numpy.all(0 <= x) and numpy.all(x < d):
        ...
    

    请参阅numpy.all 的文档。

    【讨论】:

    • 一个可能的替代方案是numpy.all((0 &lt;= x) &amp; (x &lt; d)):,但出于可读性原因,我不建议这样做。
    • @Evert 谢谢,虽然我实际上认为答案中的版本受益于短路,而这并没有,不是吗?
    • 给定x 和其他参数,这些all 测试返回False,这意味着f 只返回0.
    【解决方案3】:

    我能够通过将x 定义为一个数组并创建一个循环来单独评估每个x 来解决我的问题,不确定这是否是最有效的方法,但我只使用 1000 次迭代所以效果很好,这就是我所做的:

    def f(a,d,h,L):
    ans2=[]
    for i in range(1000):
        if (0.<=a[i]) & (a[i]<d):
            ans=x[i]*(h/d)
            ans2.append(ans)
        elif ((d<=a[i]) & (a[i]<=L)):
            ans=h*((L-a[i])/(L-d))
            ans2.append(ans)
    return ans2
    L=64.52*10**(-2)
    x=np.linspace(0,L,1000)
    h=5*10**(-3)
    d=16*10**(-2)
    plot.plot(x,f(x,d,h,L))
    

    希望它也能解决其他人的问题,如果它可以优化得更快,我很想学习。

    【讨论】:

      【解决方案4】:

      该错误与数组包含多个值有关。例如a &lt; 0,其中a = 1 具有确定的真值(假)。但是,如果 a 是一个数组怎么办。例如[-1, 0, 1],一些元素小于零,一些元素大于或等于零。那么真值应该是多少呢?为了能够创建一个真值,您必须指定是否希望所有值小于零,或者至少一个值小于零(任何 值)。

      由于 numpy 数组上的数学运算符返回数组本身,我们可以在这些数组上调用 allany 以查看所有或至少一个值是否真实。您将 if 语句重写为:

      if (0 <= x).all() and (x < d).all():
          ...
      # alternatively
      if 0 <= x.min() and x.max() < d:
          ...
      

      【讨论】:

        【解决方案5】:

        其他人已经回答,假设您想要应用一种或其他计算,具体取决于x 的所有/任何值是否满足各自的条件。我将做一个不同的假设——您想将f 分别应用于x 的每个元素。

        我得到的逐个元素应用:

        In [226]: x=np.linspace(0,1,20)
        
        In [227]: [f(z,d,h,L) for z in x]
        Out[227]: 
        [0.0,
         0.0016447368421052631,
         0.0032894736842105261,
         0.0049342105263157892,
         0.89586497157981526,
         0.78739098364212268,
         0.6789169957044302,
         0.57044300776673762,
         0.46196901982904509,
         0.35349503189135251,
         0.24502104395365998,
         0.13654705601596731,
         0.028073068078274897,
         0.0,
         0.0,
         0.0,
         0.0,
         0.0,
         0.0,
         0.0]
        

        矢量化等价物:

        In [238]: I = (0<=x) & (x<d)
        In [239]: J=(d<=x) & (x<=L)
        
        In [240]: out=np.zeros_like(x)
        In [241]: out[I]=h*(x[I]/d)
        In [242]: out[J]=(L-x[J])/(L-d)
        
        In [243]: out
        Out[243]: 
        array([ 0.        ,  0.00164474,  0.00328947,  0.00493421,  0.89586497,
                0.78739098,  0.678917  ,  0.57044301,  0.46196902,  0.35349503,
                0.24502104,  0.13654706,  0.02807307,  0.        ,  0.        ,
                0.        ,  0.        ,  0.        ,  0.        ,  0.        ])
        

        我会让你把它打包成一个函数。


        使用给定的参数(包括完整的x),np.all(I)np.all(J) 都是False,这意味着如果将f 作为一个整体应用于x,则f 将返回0.0


        def f(x, d, h, L):
           I = (0<=x) & (x<d)
           J=(d<=x) & (x<=L)
           out=np.zeros_like(x)
           out[I]=h*(x[I]/d)
           out[J]=(L-x[J])/(L-d)
           return out
        

        【讨论】:

        • 嗨。你的答案更像我正在寻找的,但是,我怎样才能将它变成x 的函数?我正在尝试制作一个 x vs. y 图,它应该看起来像一个三角形,左侧比右侧陡峭,高度 h,距离从零到 L 和 d 是沿 xy=h 的点的距离
        • 我添加了功能版本。
        【解决方案6】:
        def f(x,d,h,L):
            ans=0.
            if ((0.<=x) & (x<d)):
                ans=h*(x/d)
            elif ((d<=x) & (x<=L)):
                ans=((L-x)/(L-d))
            return ans
        
        #A ajouter
        f_vec = numpy.vectorize(f)
        #et c'est tout^^
        
        x=np.linspace(0,10,1000)
        h=5*10**(-3)
        d=16*10**(-2)
        L=64.52*10**(-2)
        func=f_vec(x,d,h,L) #ici il faut tout de même ajouter _vec
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-12
          • 2018-12-01
          • 2016-01-26
          • 2017-04-10
          • 2020-07-02
          相关资源
          最近更新 更多