首页 > 解决方案 > 使用列表理解制作要绘制的数组

问题描述

我被要求编写一些代码来制作三角波并绘制它。我最初使用 for 循环内的 if/elif 逻辑编写它。这很好用,给了我正确的结果,但它太慢了。我使用列表理解重写了代码,但情节最终有时会变形和不正确。我认为问题在于我的代码中的加法和减法。这是有效的代码:

import matplotlib.pyplot as plt
import numpy as np

f = np.linspace(-4,4,8000)
t = np.linspace(-4,4,8000)
for i in range(f.size):
    if f[i] < -3:
        f[i] = (1 - np.sqrt((f[i] + 4)**2))
    elif -3 <= f[i] < -1:
        f[i] = (1 - np.sqrt((f[i] + 2)**2))
    elif -1<= f[i] < 1:
        f[i] = (1- np.sqrt(f[i]**2))
    elif 1 <= f[i] < 3:
        f[i] = (1 - np.sqrt((f[i] - 2)**2))
    elif f[i] >= 3:
        f[i] = (1 - np.sqrt((f[i] - 4)**2))
    i += 1
    
plt.plot(t,f)
plt.show()

正确的情节:

正确的情节:

重写后的代码是:

import matplotlib.pyplot as plt
import numpy as np

f = np.linspace(-4,4,8000)
t = np.linspace(-4,4,8000)
f = [(1 - np.sqrt((i + 4)**2)) if i <= -3 else i for i in f]
f = [(1 - np.sqrt((i + 2)**2)) if -3 <= i <= -1 else i for i in f]
f = [(1 - np.sqrt(i**2)) if -1 <= i <= 1 else i for i in f]
f = [(1 - np.sqrt((i - 2)**2)) if 1 <= i <= 3 else i for i in f]
f = [(1 - np.sqrt((i - 4)**2)) if i >= 3 else i for i in f]

plt.plot(t,f)
plt.show()

我得到的问题图像是: 在此处输入图像描述

问题似乎是 1 - sqrt 的东西。我不知道如何纠正这个问题。

编辑澄清:我正在绘制三角波,但这更多是关于离散点的生成,以了解科学计算课程的 scipy 离散 fft 包。生成情节仅验证我有好点可以输入 fft。而且,经过考虑,我对性能的关注是不必要的。我认为采用我所走的原始路径将获得我想要的结果,并且未来的数据点将通过仪器为我生成,所以如果它需要 2 秒而不是 0.2 秒才能使其工作,我会很好。

标签: pythonnumpymatplotlib

解决方案


我建议您的第一种方法更可取。您可能想考虑使用 np.abs() 而不是 np.sqrt(x**2) ,因为这会稍微加快速度。或者,您可以将 8000 减少到更合理的数字,例如 100。在我的计算机上,您的代码运行时间为 200 毫秒,您需要多快?

您可能想考虑以下代码,改编自Python 中的三角形波形数组

from scipy import signal
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(-4, 4, 8000)
f = (1 - signal.sawtooth(2 * np.pi * 0.5 * t, 0.5))/2
plt.plot(t, f)

它的运行速度是原来的 10 倍


推荐阅读