numpy:对操作结果执行“任何”或“全部”的有效方法

ala*_*ani 5 python arrays numpy

假设您有两个 NumPy 数组ab,并且您想测试 的任何值a是否大于 的对应值b

现在你可以计算一个布尔数组并调用它的any方法:

(a > b).any()
Run Code Online (Sandbox Code Playgroud)

这将在内部完成所有循环,这很好,但是即使第一个结果评估为 ,也需要对所有对执行比较True

或者,您可以对标量比较进行显式循环。在ab形状相同(因此不需要广播)的情况下的示例实现可能如下所示:

any(ai > bi for ai, bi in zip(a.flatten(), b.flatten()))
Run Code Online (Sandbox Code Playgroud)

这将受益于在True遇到第一个结果后停止处理的能力,但与 Python 中的显式循环相关的所有成本(尽管在理解中)。

有没有什么办法,无论是在 NumPy 本身还是在外部库中,您都可以传入您希望执行的操作的描述,而不是该操作的结果,然后让它在内部执行操作(以优化的方式)低级代码)在一个“任何”循环中,可以从中打破?

人们可以假设某种界面,例如:

from array_operations import GreaterThan, Any

expression1 = GreaterThan('x', 'y')
expression2 = Any(expression1)

print(expression2.evaluate(x=a, y=b))
Run Code Online (Sandbox Code Playgroud)

如果存在这样的东西,就能够动态创建函数而言,它显然可以有其他用途,而不是对alland 进行有效评估any

有这样的吗?

Joh*_*nck 4

解决这个问题的一种方法是延迟/推迟/惰性评估。C++ 社区使用一种称为“表达式模板”的东西来实现这一点;您可以在这里找到可访问的概述:http://courses.csail.mit.edu/18.337/2015/projects/TylerOlsen/18337_tjolsen_ExpressionTemplates.pdf

在 Python 中,最简单的方法是使用 Numba。基本上,您只需使用循环在 Python 中编写所需的函数for,然后用它来装饰@numba.njit它就完成了。像这样:

@numba.njit
def any_greater(a, b):
    for ai, bi in zip(a.flatten(), b.flatten()): 
        if ai > bi: 
            return True 
    return False 
Run Code Online (Sandbox Code Playgroud)

有/曾经有一个 NumPy 增强提案可以帮助您的用例,但我认为它尚未实现:https ://docs.scipy.org/doc/numpy-1.13.0/neps/deferred-ufunc-评估.html