numexpr:临时变量或重复的子表达式?

numexpr: temporary variables or repeated sub-expressions?

如果同一个子表达式出现在一个 numexpr 表达式中的多个地方,它会被重新计算多次(或者 numexpr 是否足够聪明以检测到这一点并重用结果) ?

有没有办法在 numexpr 表达式中声明临时变量?这将有两个目标:

  1. 鼓励 numexpr 考虑缓存和重用结果,而不是重新计算结果;
  2. 简化表达式(使源代码更易于阅读和维护)。

我正在尝试计算 f(g(x)) 其中 fg本身都是复杂的表达式(例如,对于基于像素的主题分类,f是一个包含多个阈值的嵌套决策树,g是一组归一化差异比率,x 是多波段光栅图像)。

是的,如果子表达式在 numexpr 表达式中重复,则不会重新计算。

这可以通过将 numexpr.evaluate(expr) 替换为 numexpr.disassemble(numexpr.NumExpr(expr)) 来验证。

例如,表达式 "where(x**2 > 0.5, 0, x**2 + 10)" 被编译成如下内容:

y = x*x
t = y>0.5
y = y+10
y[t] = 0

(注意乘法只出现一次,没有出现两次。)

因此,最好将整个计算作为单个 numexpression 输入。避免在 python 中执行子计算(将中间结果或临时变量分配给 numpy 数组),因为这只会增加内存使用量并破坏 numexpr 的 optimisations/speedups(这与在 CPU-缓存大小的块以避免内存延迟)。

尽管如此,可以使用字符串替换来格式化更具可读性的代码:

f = """where({g} > 0.5,
             0,
             {g} + 10)"""
g = "x**2"
expr = f.format(g=g)