向量化一个有条件的函数

Vectorize a function with a condition

我想用一个条件向量化一个函数,意思是用数组算术计算它的值。 np.vectorize 处理矢量化,但它不适用于数组运算,因此它不是一个完整的解决方案

在问题“How to vectorize a function which contains an if statement?”中给出了答案作为解决方案,但并未防止此处出现错误;请参阅下面的 MWE。

import numpy as np

def myfx(x):
    return np.where(x < 1.1, 1, np.arcsin(1 / x))

y = myfx(x)

这会运行但会引发以下警告:

<stdin>:2: RuntimeWarning: divide by zero encountered in true_divide
<stdin>:2: RuntimeWarning: invalid value encountered in arcsin

有什么问题,或者有更好的方法吗?

我认为这可以通过

来完成
  1. 获取 x 的索引 ks,其中 x[k] > 1.1 用于 ks 中的每个 k
  2. np.arcsin(1 / x[ks]) 应用于切片 x[ks],并对其余元素使用 1。
  3. 重新组合数组。

虽然我不确定效率。

语句np.where(x < 1.1, 1, np.arcsin(1 / x))等同于

mask = x < 1.1
a = 1
b = np.arcsin(1 / x)
np.where(mask, a, b)

请注意,您正在对 x 的所有元素调用 np.arcsin,无论是否 1 / x <= 1。你的基本计划是正确的。您可以使用 np.arcsin and np.reciprocalwhere 关键字在输出数组上就地执行操作,而无需重新组合任何内容:

def myfx(x):
    mask = (x >= 1.1)
    out = np.ones(x.shape)
    np.reciprocal(x, where=mask, out=out) # >= 1.1 implies != 0
    return np.arcsin(out, where=mask, out=out)

使用 np.ones 确保 out 的未屏蔽元素被正确初始化。一个等效的方法是

out = np.empty(x.shape)
out[~mask] = 1

您总能找到防止“被零除”的算术表达式。

示例:

def myfx(x):
    return np.where( x < 1.1, 1, np.arcsin(1/np.maximum(x, 1.1)) )

右翼 x<1.1 的值未被使用,因此计算 np.arcsin(1/1.1) 其中 x < 1.1.

不是问题