【问题标题】:ValueError while applying lambda expression to elements of an array将 lambda 表达式应用于数组元素时出现 ValueError
【发布时间】:2015-12-20 14:09:33
【问题描述】:

目前我在处理 numpy.array - 4x1 - i.e 时遇到错误

[[-1.96113883]
 [-3.46144244]
 [ 5.075857  ]
 [ 1.77550086]]

使用 lambda 函数 f = lambda x: x if (x > 0) else (x * 0.01)

错误是ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我在 stackoverflow.com 上搜索了不同的主题,但我没有找到任何令人满意的问题解释和适合我的案例(许多不清楚的引用 and 运算符、矢量化代码等)。

处理数组后我期望的是一个与输入维相同的数组,并且每个单个值都根据函数进行修改,例如:

[[-0.0196113883]
 [-0.0346144244]
 [ 5.075857  ]
 [ 1.77550086]]

最后,谁能给我一个解决方案并解释为什么会发生这个错误。谢谢你的建议。

【问题讨论】:

    标签: python arrays numpy lambda runtime-error


    【解决方案1】:

    x > 0 为您的 numpy 数组作为一个整体进行评估,返回另一个布尔数组。但是,if 语句将整个数组评估为单个操作。

    arr = np.array([[-1.96113883],
                    [-3.46144244],
                    [ 5.075857  ],
                    [ 1.77550086]])
    print arr > 0
       [[False]
        [False]
        [ True]
        [ True]]
    

    如错误消息中所述,布尔数组的真值是不明确的。

    相反,如 cmets 中的 ajcr 所述,您应该使用 np.where 来进行矢量化 if-else 语句

    例如

    np.where(arr > 0, arr, arr*0.01)
    array([[-0.01961139],
           [-0.03461442],
           [ 5.075857  ],
           [ 1.77550086]])
    

    【讨论】:

    • 对于矢量化 if/else 操作,尝试使用np.where 是最快/最佳实践,例如np.where(arr > 0, arr, arr*0.01).
    • 感谢您的改进。我已经相应地更新了我的答案。
    • 感谢您的建议。我尝试使用np.vectorize 并且它有效。但是使用np.vectorizenp.where 的优缺点是什么(当然,后者的使用与if-else 的事实特别相关)?如果我必须使用其他函数来处理数组的元素,你有什么建议?
    • np.vectorize 更通用,可以用作map,但在一个numpy数组中。但是,它确实为每个元素使用了一个额外的函数调用,这在 np.where 的情况下是可以避免的。
    【解决方案2】:

    您正在尝试将 lambda 函数应用于整个数组,但您想要将其应用于每个元素。对此有更多的 numpy-y 解决方案。让您的数组为a,并将numpy 导入为np。你可以使用花哨的索引:

    >>> a_leq_0 = a <= 0
    >>> a[a_leq_0] = a[a_leq_0]*0.01
    >>> a
    array([[-0.01961139],
           [-0.03461442],
           [ 5.075857  ],
           [ 1.77550086]])
    

    甚至更好np.where:

    >>> np.where(a > 0, a, a*0.01)
    array([[-0.01961139],
           [-0.03461442],
           [ 5.075857  ],
           [ 1.77550086]])
    

    解释在where的文档中:

    where(条件, [x, y])
    [...]
    如果同时指定了xy,则输出数组包含x 的元素,其中condition 为True,元素来自 y 其他地方。

    【讨论】:

    • 我没有否决您的回复,确实我还没有获得投票的机会。无论如何,感谢您的建议。
    【解决方案3】:

    为什么不直接使用理解列表:

    np.array([list(i*0.01) if i>0 else list(i) for i in arr])
    
    Out[28]: 
    array([[-1.96113883],
           [-3.46144244],
           [ 0.05075857],
           [ 0.01775501]])
    

    数据

    arr = np.array([[-1.96113883],
     [-3.46144244],
     [ 5.075857  ],
     [ 1.77550086]])
    

    【讨论】:

    • 这会产生一个numpy数组的python列表,不符合要求。
    • 现在它产生了一个列表列表,但仍然不符合要求。您需要再次将所有内容转换回数组。
    猜你喜欢
    • 1970-01-01
    • 2014-09-16
    • 2019-06-29
    • 2018-09-05
    • 1970-01-01
    • 2012-01-12
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多