SciPy 条件函数
SciPy conditional functions
我目前正在学习 SciPy
,我想稍微玩一下 pylab
和 matplotlib
,因此作为练习,我尝试想象 Reddit
的 hot
function.
当然这段代码是行不通的,我真的不知道如何google我想要什么。
from pylab import *
import numpy as np
def f(t,v):
y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)
z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
return map(z,v)*map(y,v) + t
n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)
contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()
编辑: 不工作意味着它给我以下错误信息:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-33-a1d2f439ebda> in <module>()
13 X,Y = np.meshgrid(x,y)
14
---> 15 contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
16 C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
17 show()
<ipython-input-33-a1d2f439ebda> in f(t, v)
6 z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
7
----> 8 return map(z,v)*map(y,v) + t
9
10 n = 256
<ipython-input-33-a1d2f439ebda> in <lambda>(a)
4 y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)
5
----> 6 z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
7
8 return map(z,v)*map(y,v) + t
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
错误来自 if a > 0
,因为错误表明 a
的真值,这将是一个 NumPy 数组是不明确的。
- NumPy ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
- ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
- NumPy ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() leastsq
为什么 a
是一个 NumPy 数组而不是单个条目? Python 的 map
不会遍历数组的每个元素,它只会遍历一维并且您的输入是多维的:
>>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> f = lambda x : x
>>> map(f, a)
[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8, 9, 10, 11])]
您 可以 使用 np.vectorize
而不是 map
,这将如您所愿,但您实际上应该在 NumPy 数组上使用矢量化 NumPy 函数,其中迭代将由快速本机代码处理。以下是如何以这种方式编写代码:
import numpy as np
from pylab import *
def f(t,v):
# reproduce "y" with vectorized functions
temp_a = np.sign(v)
# reproduce "z" with vectorized functions
temp_b = np.log10(np.maximum(np.abs(v), 1.0))
# could also do something like
# abs_v = np.abs(v)
# temp_b = np.where(abs_v >= 1, np.log10(abs_v), np.log10(1))
return temp_a * temp_b + t
n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)
contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()
推荐阅读:
我还建议不要使用 pylab
,而是明确导入您需要的模块。例如在这里你会做 import matplotlib.pyplot as plt
并使用 plt.contour
和 plt.show()
。参见 Pylab discussion here and here。
我目前正在学习 SciPy
,我想稍微玩一下 pylab
和 matplotlib
,因此作为练习,我尝试想象 Reddit
的 hot
function.
当然这段代码是行不通的,我真的不知道如何google我想要什么。
from pylab import *
import numpy as np
def f(t,v):
y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)
z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
return map(z,v)*map(y,v) + t
n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)
contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()
编辑: 不工作意味着它给我以下错误信息:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-33-a1d2f439ebda> in <module>()
13 X,Y = np.meshgrid(x,y)
14
---> 15 contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
16 C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
17 show()
<ipython-input-33-a1d2f439ebda> in f(t, v)
6 z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
7
----> 8 return map(z,v)*map(y,v) + t
9
10 n = 256
<ipython-input-33-a1d2f439ebda> in <lambda>(a)
4 y = lambda a : 1 if a > 0 else (-1 if a < 0 else 0)
5
----> 6 z = lambda a : log10(abs(a)) if abs(a) >= 1 else log10(1)
7
8 return map(z,v)*map(y,v) + t
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
错误来自 if a > 0
,因为错误表明 a
的真值,这将是一个 NumPy 数组是不明确的。
- NumPy ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
- ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
- NumPy ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() leastsq
为什么 a
是一个 NumPy 数组而不是单个条目? Python 的 map
不会遍历数组的每个元素,它只会遍历一维并且您的输入是多维的:
>>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> f = lambda x : x
>>> map(f, a)
[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8, 9, 10, 11])]
您 可以 使用 np.vectorize
而不是 map
,这将如您所愿,但您实际上应该在 NumPy 数组上使用矢量化 NumPy 函数,其中迭代将由快速本机代码处理。以下是如何以这种方式编写代码:
import numpy as np
from pylab import *
def f(t,v):
# reproduce "y" with vectorized functions
temp_a = np.sign(v)
# reproduce "z" with vectorized functions
temp_b = np.log10(np.maximum(np.abs(v), 1.0))
# could also do something like
# abs_v = np.abs(v)
# temp_b = np.where(abs_v >= 1, np.log10(abs_v), np.log10(1))
return temp_a * temp_b + t
n = 256
x = np.linspace(0,100,n)
y = np.linspace(-50,+50,n)
X,Y = np.meshgrid(x,y)
contourf(X, Y, f(X,Y), 15, alpha=.75, cmap='jet')
C = contour(X, Y, f(X,Y), 15, colors='black', linewidth=.5)
show()
推荐阅读:
我还建议不要使用 pylab
,而是明确导入您需要的模块。例如在这里你会做 import matplotlib.pyplot as plt
并使用 plt.contour
和 plt.show()
。参见 Pylab discussion here and here。