数据没有变化的 FFT 时间序列?
FFT time series with no change in data?
我想计算快速傅立叶变换,我想查看网络数据包在网络上的发送速率。为此,我计算每秒发送的数据包。
有些数据包的发送速率为1Hz,导致这个时间序列数据:[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
有没有办法在这个数组上执行 FFT
?我总是得到 0Hz
作为结果。或者这不是 FFT
的情况吗?
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1]
工作正常..
所以基本上我想改变这个:
进入这个:
在深入研究问题的细节之前,让我们使用时间序列术语来说明一些理论。
给定某个函数 f(t)
,这可以以特定频率 Δt
采样一段时间 T = n * Δt
称为持续时间(n
是样本数)。
现在,您可以将离散傅立叶变换 (DFT) 应用于 f(t)
,并获得频率分布 F(ν)
,这也是一个具有相同样本数 n
的(复数)函数。
我假设你熟悉频率分布的含义,我不会进一步讨论这个。
我想在这里强调的唯一 属性 是 DFT 是循环定义的,这意味着假设 f(t) = f(t + T)
对所有 t
类似地 F(ν) = F(ν + Ν)
对于所有 ν
(Ν
是频率周期),即它们都是周期性的。
现在的基本问题是:F(ν)
的 ν
的采样 Δν
和持续时间 Ν
是多少? Wikipedia当然知道这一点。
您可能会猜到,这与 Δt
和 T
有关。
特别是:Δν = 1 / T
因此 Ν = n * Δν = 1 / Δt
.
NumPy 使用快速傅里叶变换 (FFT) 算法实现 DFT,该算法在 F(ν)
方面具有一些很好的特性,最值得注意的是它总是计算第 0 个频率(即 F(ν = 0)
)并且在如果没有移位,这也是 F(ν)
的第一个系数。
请注意,由于 F(ν)
的周期性,negative 频率实际上在 positive 频率之后。
要使 F_ν
以 F(ν = 0)
为中心,您必须使用:np.fft.fftshift()
。
如果n
是偶数,F(ν = 0)
是F_ν
右半部分的第一个值,需要格外注意正确定义ν_shift
,用负数表示F(ν)
和正 ν
值。
要了解绘图应该是什么,请再次参考 Wikipedia 以了解著名的傅里叶变换函数对。
为了用代码说明这一切,这里有一些计算两个正弦波叠加的 DFT:
import numpy as np
import matplotlib.pyplot as plt
π = np.pi
# Number of samples
n = 400
# Time uration and sampling
T = 80
Δt = T / n
print(f'Δt = {Δt}, T = {T}')
# Δt = 0.2, T = 80
# Frequency duration and sampling
Δν = 1 / T
Ν = 1 / Δt # or: n * Δν
print(f'Δν = {Δν}, Ν = {Ν}')
# Δν = 0.0125, Ν = 5.0
# Define time and frequency (endpoint=False takes care of periodicity)
t = np.linspace(0, T, n, endpoint=False)
ν = np.linspace(0, Ν, n, endpoint=False)
# Generate a certain f(t) = A₀ sin(ν₀ * 2πt) + A₁ sin(ν₁ * 2πt)
ν_ = 1, 2
A_ = 1, 3
f_t = A_[0] * np.sin(ν_[0] * 2 * π * t) + A_[1] * np.sin(ν_[1] * 2 * π * t)
# Compute the F(ν) as the DFT(f(t))
# F(ν) ∝ A₀ (δ(ν - ν₀) + δ(ν + ν₀)) + A₁ (δ(ν - ν₁) + δ(ν + ν₁))
# δ is the [Dirac Delta function][3]
F_ν = np.fft.fft(f_t)
# Center F(ν) around ν = 0
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
# Plot the result
fig, axs = plt.subplots(1, 3, figsize=(16, 4), squeeze=False)
axs[0, 0].plot(t, f_t)
axs[0, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[0, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[0, 1].axvline(ν_[0], color='green')
axs[0, 1].axvline(ν_[1], color='orange')
axs[0, 2].axvline(ν_[0], color='green')
axs[0, 2].axvline(ν_[1], color='orange')
plt.show()
(您可能应该尝试一下上面的代码以了解 FFT 在做什么)。
请注意,在所有这些中,采样频率并未在 F(ν)
中显示为峰值!它确实起到了作用,但是在像aliasing and spectral leakage, both related to the Shannon-Nyquist theorem.
这样的效果中
现在,对于您的问题,您正在比较 f_t
,而这基本上是一个常数——其傅里叶变换是以 ν = 0
、δ(0)
为中心的狄拉克三角洲——并且当这是一个交替函数时,可以将其视为 ν₀ = Ν / 2
的 sin(ν₀ * 2πt)
- 其傅立叶变换(如前)与 ν = ±ν₀ = ±Ν / 2
.[=65 处狄拉克三角洲的总和成正比=]
下面的代码将帮助您直观地了解正在发生的事情:
import numpy as np
import matplotlib.pyplot as plt
π = np.pi
# Number of samples
n = 20
# Time duration and sampling
T = 20
Δt = T / n
# Frequency duration and sampling
Δν = 1 / T
Ν = 1 / Δt
# Define time and frequency
t = np.linspace(0, T, n, endpoint=False)
ν = np.linspace(0, Ν, n, endpoint=False)
# Plot the result
fig, axs = plt.subplots(2, 3, figsize=(16, 8), squeeze=False)
# Plotting DFT for constant function
f_t = np.array([1 for _ in range(n)])
F_ν = np.fft.fft(f_t)
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
axs[0, 0].plot(t, f_t)
axs[0, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[0, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[0, 1].axvline(0, color='green')
axs[0, 2].axvline(0, color='green')
# Plotting DFT for an alternating function
f_t = np.array([i % 2 for i in range(n)])
F_ν = np.fft.fft(f_t)
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
axs[1, 0].plot(t, f_t)
axs[1, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[1, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[1, 1].axvline(0, color='green')
axs[1, 1].axvline(Ν / 2, color='orange')
axs[1, 2].axvline(0, color='green')
axs[1, 2].axvline(Ν / 2, color='orange')
axs[1, 2].axvline(-Ν / 2, color='orange')
plt.show()
(请注意 ν = +Ν / 2
处的峰值实际上并不存在,因为当 n
为偶数时,正 频率比 负 频率,峰值正好在边缘。)
我们可以观察到交替序列的非移位 FFT 中间有一个峰值,而恒定序列不存在该峰值。
因此,您观察到的是正确的,但您的解释是错误的。
如果我们假设常数和交替f(t)
是在相同的采样率下得到的,那么我们可以得出结论,采样率与F(ν)
的出现没有关系。
另一方面,如果我们假设常数和交替f(t)
是同一事件以不同采样率进行的两次采样,而交替是在更高的采样率下获得的(这不是上图中描述的情况),那么我们可以得出结论,在 ν = ±Ν / 2 = ±1 / (2 Δt)
处出现额外的峰值与函数出现常数时 f(t)
的采样不足有关。
这些new峰的位置就是前面提到的aliasing which is related to the Shannon-Nyquist theorem的表现。
最后,如果你想观察网络流量分析,单位时间内的数据包数量IS已经"the rate that network packets are send over the network" .
我想计算快速傅立叶变换,我想查看网络数据包在网络上的发送速率。为此,我计算每秒发送的数据包。
有些数据包的发送速率为1Hz,导致这个时间序列数据:[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
有没有办法在这个数组上执行 FFT
?我总是得到 0Hz
作为结果。或者这不是 FFT
的情况吗?
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1]
工作正常..
所以基本上我想改变这个:
进入这个:
在深入研究问题的细节之前,让我们使用时间序列术语来说明一些理论。
给定某个函数 f(t)
,这可以以特定频率 Δt
采样一段时间 T = n * Δt
称为持续时间(n
是样本数)。
现在,您可以将离散傅立叶变换 (DFT) 应用于 f(t)
,并获得频率分布 F(ν)
,这也是一个具有相同样本数 n
的(复数)函数。
我假设你熟悉频率分布的含义,我不会进一步讨论这个。
我想在这里强调的唯一 属性 是 DFT 是循环定义的,这意味着假设 f(t) = f(t + T)
对所有 t
类似地 F(ν) = F(ν + Ν)
对于所有 ν
(Ν
是频率周期),即它们都是周期性的。
现在的基本问题是:F(ν)
的 ν
的采样 Δν
和持续时间 Ν
是多少? Wikipedia当然知道这一点。
您可能会猜到,这与 Δt
和 T
有关。
特别是:Δν = 1 / T
因此 Ν = n * Δν = 1 / Δt
.
NumPy 使用快速傅里叶变换 (FFT) 算法实现 DFT,该算法在 F(ν)
方面具有一些很好的特性,最值得注意的是它总是计算第 0 个频率(即 F(ν = 0)
)并且在如果没有移位,这也是 F(ν)
的第一个系数。
请注意,由于 F(ν)
的周期性,negative 频率实际上在 positive 频率之后。
要使 F_ν
以 F(ν = 0)
为中心,您必须使用:np.fft.fftshift()
。
如果n
是偶数,F(ν = 0)
是F_ν
右半部分的第一个值,需要格外注意正确定义ν_shift
,用负数表示F(ν)
和正 ν
值。
要了解绘图应该是什么,请再次参考 Wikipedia 以了解著名的傅里叶变换函数对。
为了用代码说明这一切,这里有一些计算两个正弦波叠加的 DFT:
import numpy as np
import matplotlib.pyplot as plt
π = np.pi
# Number of samples
n = 400
# Time uration and sampling
T = 80
Δt = T / n
print(f'Δt = {Δt}, T = {T}')
# Δt = 0.2, T = 80
# Frequency duration and sampling
Δν = 1 / T
Ν = 1 / Δt # or: n * Δν
print(f'Δν = {Δν}, Ν = {Ν}')
# Δν = 0.0125, Ν = 5.0
# Define time and frequency (endpoint=False takes care of periodicity)
t = np.linspace(0, T, n, endpoint=False)
ν = np.linspace(0, Ν, n, endpoint=False)
# Generate a certain f(t) = A₀ sin(ν₀ * 2πt) + A₁ sin(ν₁ * 2πt)
ν_ = 1, 2
A_ = 1, 3
f_t = A_[0] * np.sin(ν_[0] * 2 * π * t) + A_[1] * np.sin(ν_[1] * 2 * π * t)
# Compute the F(ν) as the DFT(f(t))
# F(ν) ∝ A₀ (δ(ν - ν₀) + δ(ν + ν₀)) + A₁ (δ(ν - ν₁) + δ(ν + ν₁))
# δ is the [Dirac Delta function][3]
F_ν = np.fft.fft(f_t)
# Center F(ν) around ν = 0
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
# Plot the result
fig, axs = plt.subplots(1, 3, figsize=(16, 4), squeeze=False)
axs[0, 0].plot(t, f_t)
axs[0, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[0, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[0, 1].axvline(ν_[0], color='green')
axs[0, 1].axvline(ν_[1], color='orange')
axs[0, 2].axvline(ν_[0], color='green')
axs[0, 2].axvline(ν_[1], color='orange')
plt.show()
(您可能应该尝试一下上面的代码以了解 FFT 在做什么)。
请注意,在所有这些中,采样频率并未在 F(ν)
中显示为峰值!它确实起到了作用,但是在像aliasing and spectral leakage, both related to the Shannon-Nyquist theorem.
现在,对于您的问题,您正在比较 f_t
,而这基本上是一个常数——其傅里叶变换是以 ν = 0
、δ(0)
为中心的狄拉克三角洲——并且当这是一个交替函数时,可以将其视为 ν₀ = Ν / 2
的 sin(ν₀ * 2πt)
- 其傅立叶变换(如前)与 ν = ±ν₀ = ±Ν / 2
.[=65 处狄拉克三角洲的总和成正比=]
下面的代码将帮助您直观地了解正在发生的事情:
import numpy as np
import matplotlib.pyplot as plt
π = np.pi
# Number of samples
n = 20
# Time duration and sampling
T = 20
Δt = T / n
# Frequency duration and sampling
Δν = 1 / T
Ν = 1 / Δt
# Define time and frequency
t = np.linspace(0, T, n, endpoint=False)
ν = np.linspace(0, Ν, n, endpoint=False)
# Plot the result
fig, axs = plt.subplots(2, 3, figsize=(16, 8), squeeze=False)
# Plotting DFT for constant function
f_t = np.array([1 for _ in range(n)])
F_ν = np.fft.fft(f_t)
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
axs[0, 0].plot(t, f_t)
axs[0, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[0, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[0, 1].axvline(0, color='green')
axs[0, 2].axvline(0, color='green')
# Plotting DFT for an alternating function
f_t = np.array([i % 2 for i in range(n)])
F_ν = np.fft.fft(f_t)
F_ν_shift = np.fft.fftshift(F_ν)
ν_shift = ν - (Ν / 2) + (Δν / 2 if n % 2 else 0)
axs[1, 0].plot(t, f_t)
axs[1, 1].plot(ν, 2.0 / n * np.abs(F_ν))
axs[1, 2].plot(ν_shift, 2.0 / n * np.abs(F_ν_shift))
axs[1, 1].axvline(0, color='green')
axs[1, 1].axvline(Ν / 2, color='orange')
axs[1, 2].axvline(0, color='green')
axs[1, 2].axvline(Ν / 2, color='orange')
axs[1, 2].axvline(-Ν / 2, color='orange')
plt.show()
(请注意 ν = +Ν / 2
处的峰值实际上并不存在,因为当 n
为偶数时,正 频率比 负 频率,峰值正好在边缘。)
我们可以观察到交替序列的非移位 FFT 中间有一个峰值,而恒定序列不存在该峰值。
因此,您观察到的是正确的,但您的解释是错误的。
如果我们假设常数和交替f(t)
是在相同的采样率下得到的,那么我们可以得出结论,采样率与F(ν)
的出现没有关系。
另一方面,如果我们假设常数和交替f(t)
是同一事件以不同采样率进行的两次采样,而交替是在更高的采样率下获得的(这不是上图中描述的情况),那么我们可以得出结论,在 ν = ±Ν / 2 = ±1 / (2 Δt)
处出现额外的峰值与函数出现常数时 f(t)
的采样不足有关。
这些new峰的位置就是前面提到的aliasing which is related to the Shannon-Nyquist theorem的表现。
最后,如果你想观察网络流量分析,单位时间内的数据包数量IS已经"the rate that network packets are send over the network" .