在Python中,如何以矢量化的方式而不是在循环中计算值数组?
问题是: 编写并测试一个Python脚本,该脚本从输入中接受最多5个指数n值的列表,并在同一个图形上绘制y=1/(x^n+1)的曲线。程序应该为x和y_0,y_1。。。最多y_4个值。x坐标数组应由-10和10(包括-10和10)之间的201个等距值组成您应该通过对x执行矢量化操作来计算y值(不要在循环中一次计算一个y值)。用蓝色在图形上绘制y_0与x,用红色、绿色、青色和洋红在同一图形上绘制y_1(以此类推)与x。应沿x轴、y轴和栅格的轴标签在绘图上放置标题。准备好后,请记住使用show()函数 不带参数的show()命令将暂停代码执行。您的程序应在屏幕上打印一条消息,提醒用户关闭绘图窗口,以便程序继续。一旦用户关闭图形,您的程序应返回并允许用户输入另一个n值序列。程序应接受n的任何浮点值,并在输入“q”作为第一个值时终止。如果输入“q”作为第二、第三、第四或第五个值,则程序应生成仅包含这些值的绘图(例如,如果输入2、4、6、q,则程序应生成仅包含三条蓝色、红色和绿色曲线的绘图,然后返回以获取更多输入)。对于所有其他输入,程序应打印一条消息,指示存在问题,并要求用户再次输入n值。(提示:在尝试将输入字符串转换为float之前,如果float转换不起作用,可以尝试使用ValueError的except子句。)程序不应在输入错误时终止。运行程序n=2,4,8,'fred',16,32,(这将生成一个图形),然后n=2,4,9和,q(这将生成另一个图形…并可能出现关于除以0的运行时警告…),然后“q”终止 输出应该与下面的内容类似。请注意,title、xlabel和ylabel pyplot命令接受可以使用format方法将变量合并到字符串中的字符串在Python中,如何以矢量化的方式而不是在循环中计算值数组?,python,numpy,matplotlib,Python,Numpy,Matplotlib,问题是: 编写并测试一个Python脚本,该脚本从输入中接受最多5个指数n值的列表,并在同一个图形上绘制y=1/(x^n+1)的曲线。程序应该为x和y_0,y_1。。。最多y_4个值。x坐标数组应由-10和10(包括-10和10)之间的201个等距值组成您应该通过对x执行矢量化操作来计算y值(不要在循环中一次计算一个y值)。用蓝色在图形上绘制y_0与x,用红色、绿色、青色和洋红在同一图形上绘制y_1(以此类推)与x。应沿x轴、y轴和栅格的轴标签在绘图上放置标题。准备好后,请记住使用show()函
Enter exponent n (q to quit)>2
Enter exponent n (q to quit)>4
Enter exponent n (q to quit)>8
Enter exponent n (q to quit)>fred
That's not a number!!!
Enter exponent n (q to quit)>16
Enter exponent n (q to quit)>32
Close plot window to continue...
我的代码是:
import numpy as np
import matplotlib.pyplot as mplt
import sys
while True:
try:
n_list = []
for i in range(5):
exponent = input('Enter exponent n (q to quit)>')
n_list.insert(i,float(exponent))
except ValueError:
if exponent == 'q' and i == 0:
sys.exit()
elif exponent == 'q' and i != 0:
break
else:
print('That\'s not a number!!!')
for j in range(i,5):
exponent = input('Enter exponent n (q to quit)>')
n_list.insert(j,float(exponent))
finally:
if exponent == 'q' and i == 0:
sys.exit()
print(n_list)
x = np.linspace(-10,10,num=201)
y1 = 1/((x**n_list[0])+1)
y2 = 1/((x**n_list[1])+1)
y3 = 1/((x**n_list[2])+1)
y4 = 1/((x**n_list[3])+1)
y5 = 1/((x**n_list[4])+1)
mplt.plot(x,y1,'b-')
mplt.plot(x,y2,'r-')
mplt.plot(x,y3,'g-')
mplt.plot(x,y4,'c-')
mplt.plot(x,y5,'m-')
mplt.title('$1/(x^n+1)$, n={}'.format(n_list))
mplt.xlabel('x')
mplt.ylabel('f(x)')
mplt.grid(True)
print('Close plot window to continue...')
mplt.show()
我的输出是:
Enter exponent n (q to quit)>2
Enter exponent n (q to quit)>4
Enter exponent n (q to quit)>8
Enter exponent n (q to quit)>fred
That's not a number!!!
Enter exponent n (q to quit)>16
Enter exponent n (q to quit)>32
当我给出我的输出时:
Enter exponent n (q to quit)>2
Enter exponent n (q to quit)>4
Enter exponent n (q to quit)>9
Enter exponent n (q to quit)>q
That's not a number
Enter exponent n (q to quit)>
问题是,在第一次输入q之后,程序不会退出。当输入2、4、9、q时,有人能解释一下第二部分的逻辑吗?还有没有其他方法可以计算y值
提前谢谢 实际上,我没有您提到的问题,但是在第二种情况下,它无法为
I==3
和I==4
创建绘图,因为没有这样的列表元素
我已经尝试过了,因为我喜欢清晰的编程风格和函数,所以我创建了一个小脚本来满足您的需要。(最初我尝试了你的解决方案,但我总是遇到一些错误,最后我只是尝试自己实现它)。我希望这些评论能传达出我为什么这样做:
import numpy as np
import matplotlib.pyplot as mplt
import sys
def getinput():
n_list = []
# Use a while loop instead of a for loop
while len(n_list) < 5:
# Get some number
exponent = input('Enter exponent n (q to quit)>')
# This will fail with a ValueError if it cannot be converted to float
try:
n_list.append(float(exponent))
# Never use bare except statements!
except ValueError:
if exponent == 'q':
if n_list:
# empty lists evaluate to False so we have some elements
# Returning them breaks the loop and exits the function
return n_list
else:
# We had no elements in the list so just exit
sys.exit()
# It wasn't q so it was a bad input
else:
print('That is not a number!!!')
return n_list
def plotthem(n_list):
x = np.linspace(-10,10,num=201)
style = ['b-', 'r-', 'g-', 'c-','m-']
# Only plot as many lines as there are objects in the list (and use the appropriate style)
for i in range(len(n_list)):
mplt.plot(x, 1/((x**n_list[i])+1), style[i])
mplt.title('$1/(x^n+1)$, n={}'.format(n_list))
mplt.xlabel('x')
mplt.ylabel('f(x)')
mplt.grid(True)
print('Close plot window to continue...')
mplt.show()
# If started as script
if __name__ == "__main__":
while True:
plotthem(getinput())
在代码中,如果指数=='q'和i==0:,则有一行
。为什么使用i==0
语句?程序应该只在第一个输入为q时退出,因此i==0检查输入的q是否是第一个。那么您如何查找指数为'q'
但不是输入的第一个值的情况?MSeifert,我真的必须欣赏您的编码风格,但是我可以看到,在这里,你已经间接地计算了循环中I的y值(len(n_list)):mplt.plot(x,1/((x**n_list[I])+1),style[I])。问题明确地说,你应该通过对x执行向量化操作来计算y值(不要在循环中一次计算一个y值)。那么,考虑到这一点,我们该如何做呢?@Cute_Parrot-1/((x**n_list[i])+1)
仍然是一个矢量化操作。作业上说你不应该循环x
,但是你可以循环n\u list
:)@Cute\u Parrot-Eveen尽管我同意晨星的观点,并且认为这已经足够矢量化了:我在答案的末尾包含了一个完全矢量化的解决方案,只需插入这个循环,而不是前一个循环。@MSeifert-我有点了解正在发生的事情,并感谢y=1/((x[None,:]**np.array(n_list)[:,None])+1)
但是,是否有可能解释到底发生了什么,或者它做了什么?
Enter exponent n (q to quit)>2
Enter exponent n (q to quit)>4
Enter exponent n (q to quit)>9
Enter exponent n (q to quit)>q
That's not a number
Enter exponent n (q to quit)>
import numpy as np
import matplotlib.pyplot as mplt
import sys
def getinput():
n_list = []
# Use a while loop instead of a for loop
while len(n_list) < 5:
# Get some number
exponent = input('Enter exponent n (q to quit)>')
# This will fail with a ValueError if it cannot be converted to float
try:
n_list.append(float(exponent))
# Never use bare except statements!
except ValueError:
if exponent == 'q':
if n_list:
# empty lists evaluate to False so we have some elements
# Returning them breaks the loop and exits the function
return n_list
else:
# We had no elements in the list so just exit
sys.exit()
# It wasn't q so it was a bad input
else:
print('That is not a number!!!')
return n_list
def plotthem(n_list):
x = np.linspace(-10,10,num=201)
style = ['b-', 'r-', 'g-', 'c-','m-']
# Only plot as many lines as there are objects in the list (and use the appropriate style)
for i in range(len(n_list)):
mplt.plot(x, 1/((x**n_list[i])+1), style[i])
mplt.title('$1/(x^n+1)$, n={}'.format(n_list))
mplt.xlabel('x')
mplt.ylabel('f(x)')
mplt.grid(True)
print('Close plot window to continue...')
mplt.show()
# If started as script
if __name__ == "__main__":
while True:
plotthem(getinput())
# Completly vectorized solution - result has shape (len(n_list), 201)
y = 1/((x[None,:]**np.array(n_list)[:,None])+1)
for i in range(len(n_list)):
# Now change this to plotting the i-th row of y
mplt.plot(x, y[i], style[i])