numexpr:临时变量或重复的子表达式?
numexpr: temporary variables or repeated sub-expressions?
如果同一个子表达式出现在一个 numexpr 表达式中的多个地方,它会被重新计算多次(或者 numexpr 是否足够聪明以检测到这一点并重用结果) ?
有没有办法在 numexpr 表达式中声明临时变量?这将有两个目标:
- 鼓励 numexpr 考虑缓存和重用结果,而不是重新计算结果;
- 简化表达式(使源代码更易于阅读和维护)。
我正在尝试计算 f(g(x)) 其中 f 和 g本身都是复杂的表达式(例如,对于基于像素的主题分类,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)
如果同一个子表达式出现在一个 numexpr 表达式中的多个地方,它会被重新计算多次(或者 numexpr 是否足够聪明以检测到这一点并重用结果) ?
有没有办法在 numexpr 表达式中声明临时变量?这将有两个目标:
- 鼓励 numexpr 考虑缓存和重用结果,而不是重新计算结果;
- 简化表达式(使源代码更易于阅读和维护)。
我正在尝试计算 f(g(x)) 其中 f 和 g本身都是复杂的表达式(例如,对于基于像素的主题分类,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)