对 numpy 元组进行矢量化时函数返回意外值
Function returning unexpected values when vectorizing over numpy tuple
我想快速看一下下面的分布函数,发现我尝试这样做的方式有问题。将函数应用于 x_range
时,所有值最终都是 0
。我对此感到非常困惑,并且很难理解为什么会这样。在这种情况下我使用 numpy 错了吗?至少这是我唯一的解释,但我无法找到任何解释为什么我会看到这些结果。
下面是我的代码。
from matplotlib import pyplot as plt
import numpy as np
def F(x):
return 0 if x <= 0 \
else .0025 * x if x <= 100 \
else .25 if x <= 200 \
else .0025 * x - .25 if x <= 300 \
else .0025 * x if x <= 400 \
else 1
x_range = np.linspace(0, 410, 1000)
plt.plot(np.vectorize(F)(x_range))
plt.show()
另外,有没有人知道一种更优雅的方法来简单地绘制一个区间内的函数?我不太喜欢将函数矢量化并将其应用于专门生成的数组以仅用于绘图。我假设应该有内置的 matplotlib 功能来在 R
.
的某些子空间上绘制函数
也许将“if 语句”中的数字从 int 更改为 float 可能会有所帮助:
def F(x):
return 0.0 if x <= 0.0 \
else 0.0025 * x if x <= 100.0 \
else 0.25 if x <= 200.0 \
else 0.0025 * x - 0.25 if x <= 300.0 \
else 0.0025 * x if x <= 400.0 \
else 1.0
vectorize
的文档说:
The data type of the output of vectorized is determined by calling the function with the first element of the input. This can be avoided by specifying the otypes argument.
由于您的第一个输出是一个整数,它认为您需要整数。如果你传递你想要的输出类型 otypes
你的问题就消失了:
from matplotlib import pyplot as plt
import numpy as np
def F(x):
return 0 if x <= 0 \
else .0025 * x if x <= 100 \
else .25 if x <= 200 \
else .0025 * x - .25 if x <= 300 \
else .0025 * x if x <= 400 \
else 1
x_range = np.linspace(0, 410, 1000)
plt.plot(np.vectorize(F, otypes=[float])(x_range))
plt.show()
将 F
更正为一致 return 浮点数:
In [45]: def F(x):
...: return .0 if x <= 0 \
...: else .0025 * x if x <= 100 \
...: else .25 if x <= 200 \
...: else .0025 * x - .25 if x <= 300 \
...: else .0025 * x if x <= 400 \
...: else 1.0
...:
还有更小的 x
:
In [46]: x = np.linspace(0,410,11)
In [47]: x
Out[47]: array([ 0., 41., 82., 123., 164., 205., 246., 287., 328., 369., 410.])
vectorize
与 otypes
:
In [48]: np.vectorize(F,otypes=[float])(x)
Out[48]:
array([0. , 0.1025, 0.205 , 0.25 , 0.25 , 0.2625, 0.365 , 0.4675,
0.82 , 0.9225, 1.0 ])
和使用列表理解的相同的东西:
In [49]: np.array([F(i) for i in x])
Out[49]:
array([0. , 0.1025, 0.205 , 0.25 , 0.25 , 0.2625, 0.365 , 0.4675,
0.82 , 0.9225, 1.0 ])
对于这个小 x
列表理解更快;对于大 x_range
,vectorize
更快。
“真正矢量化”的计算是:
def foo(x):
res = np.zeros(x.shape)
mask = (x>0) & (x<=100); res[mask] = 0.0025*x[mask]
mask = (x>100) & (x<=200); res[mask] = .25
mask = (x>200) & (x<=300); res[mask] = 0.0025*x[mask]-.25
mask = (x>300) & (x<=400); res[mask] = 0.0025*x[mask]
mask = (x>400); res[mask] = 1
return res
对于我的 10 元素 x
速度较慢,但对于大 x_range
尺度要好得多。
我想快速看一下下面的分布函数,发现我尝试这样做的方式有问题。将函数应用于 x_range
时,所有值最终都是 0
。我对此感到非常困惑,并且很难理解为什么会这样。在这种情况下我使用 numpy 错了吗?至少这是我唯一的解释,但我无法找到任何解释为什么我会看到这些结果。
下面是我的代码。
from matplotlib import pyplot as plt
import numpy as np
def F(x):
return 0 if x <= 0 \
else .0025 * x if x <= 100 \
else .25 if x <= 200 \
else .0025 * x - .25 if x <= 300 \
else .0025 * x if x <= 400 \
else 1
x_range = np.linspace(0, 410, 1000)
plt.plot(np.vectorize(F)(x_range))
plt.show()
另外,有没有人知道一种更优雅的方法来简单地绘制一个区间内的函数?我不太喜欢将函数矢量化并将其应用于专门生成的数组以仅用于绘图。我假设应该有内置的 matplotlib 功能来在 R
.
也许将“if 语句”中的数字从 int 更改为 float 可能会有所帮助:
def F(x):
return 0.0 if x <= 0.0 \
else 0.0025 * x if x <= 100.0 \
else 0.25 if x <= 200.0 \
else 0.0025 * x - 0.25 if x <= 300.0 \
else 0.0025 * x if x <= 400.0 \
else 1.0
vectorize
的文档说:
The data type of the output of vectorized is determined by calling the function with the first element of the input. This can be avoided by specifying the otypes argument.
由于您的第一个输出是一个整数,它认为您需要整数。如果你传递你想要的输出类型 otypes
你的问题就消失了:
from matplotlib import pyplot as plt
import numpy as np
def F(x):
return 0 if x <= 0 \
else .0025 * x if x <= 100 \
else .25 if x <= 200 \
else .0025 * x - .25 if x <= 300 \
else .0025 * x if x <= 400 \
else 1
x_range = np.linspace(0, 410, 1000)
plt.plot(np.vectorize(F, otypes=[float])(x_range))
plt.show()
将 F
更正为一致 return 浮点数:
In [45]: def F(x):
...: return .0 if x <= 0 \
...: else .0025 * x if x <= 100 \
...: else .25 if x <= 200 \
...: else .0025 * x - .25 if x <= 300 \
...: else .0025 * x if x <= 400 \
...: else 1.0
...:
还有更小的 x
:
In [46]: x = np.linspace(0,410,11)
In [47]: x
Out[47]: array([ 0., 41., 82., 123., 164., 205., 246., 287., 328., 369., 410.])
vectorize
与 otypes
:
In [48]: np.vectorize(F,otypes=[float])(x)
Out[48]:
array([0. , 0.1025, 0.205 , 0.25 , 0.25 , 0.2625, 0.365 , 0.4675,
0.82 , 0.9225, 1.0 ])
和使用列表理解的相同的东西:
In [49]: np.array([F(i) for i in x])
Out[49]:
array([0. , 0.1025, 0.205 , 0.25 , 0.25 , 0.2625, 0.365 , 0.4675,
0.82 , 0.9225, 1.0 ])
对于这个小 x
列表理解更快;对于大 x_range
,vectorize
更快。
“真正矢量化”的计算是:
def foo(x):
res = np.zeros(x.shape)
mask = (x>0) & (x<=100); res[mask] = 0.0025*x[mask]
mask = (x>100) & (x<=200); res[mask] = .25
mask = (x>200) & (x<=300); res[mask] = 0.0025*x[mask]-.25
mask = (x>300) & (x<=400); res[mask] = 0.0025*x[mask]
mask = (x>400); res[mask] = 1
return res
对于我的 10 元素 x
速度较慢,但对于大 x_range
尺度要好得多。