You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将FFT频谱图的X轴频率值转换为有意义的时间周期?

问题:将FFT得到的频率值转换为有意义的时间周期指标

本人是编程新手,现有一份跨度为一年、采样间隔15分钟的电池SOC(State of Charge)时间序列数据,希望通过FFT分析识别小时、周、月等充放电周期。编写了如下代码:

from numpy.fft import fft, fftfreq, ifft 
import matplotlib.pyplot as plt, mpld3
import numpy as np  # 注:原代码遗漏numpy导入,建议补充

# setup domain
# number of points (15 min intervals within 1 year)
nl = 34943

# length of watched domain 
# 1 year in hours
lx    = 34943/4

# creating x-axis
x = np.linspace(0, lx, nl)

# full signal
# dataset of different values throughout the year
y = np.array(df['SOC_batt'])

# creating necessary frequencies
freqs = fftfreq(nl)

# splitting frequencies in half 
mask = freqs > 0 

# fft values
fft_vals = fft(y)

# true theoretical fft
fft_theo = 2.0*np.abs(fft_vals/nl)

plt.figure(1)
plt.title('original data')
plt.plot(x, y, color='xkcd:salmon')

plt.figure(2)
# fft processed
plt.plot(freqs[mask], fft_theo[mask], label='true fft values')
plt.title('true fft values')
mpld3.display()

运行代码后得到FFT频谱图,放大后获取到峰值对应的X轴频率值:

# first peak of 4 at 0.01041
# second peak of 5 at 0.02083
# third peak of 1.1 at 0.03125

现咨询如何将这些频率值转换为与全年数据相关的、更有意义的时间周期指标?


解决方案

核心转换逻辑

FFT输出的频率单位由采样间隔和x轴定义决定:

  • 你当前用fftfreq(nl)得到的频率,单位是每采样点的周期数(每个采样点对应15分钟/0.25小时)
  • 要得到时间周期(完成一次充放电循环的时长),只需基于采样间隔做倒数换算:
    周期(小时) = 采样间隔(小时) / 频率值
    

代入峰值计算验证

你的采样间隔是0.25小时,代入三个峰值频率:

  • 第一个峰值(0.01041):0.25 / 0.01041 ≈ 24小时(正好是日周期)
  • 第二个峰值(0.02083):0.25 / 0.02083 ≈ 12小时(半日周期,对应一天两次充放电)
  • 第三个峰值(0.03125):0.25 / 0.03125 = 8小时(每8小时一次循环)

优化代码:直接显示周期(更直观)

修改代码,让频谱图直接以小时/天为单位展示周期,同时修正原代码的细节问题:

from numpy.fft import fft, fftfreq, ifft 
import matplotlib.pyplot as plt, mpld3
import numpy as np

nl = 34943
dt = 0.25  # 采样间隔:0.25小时(15分钟)
lx = nl * dt  # 总时长:采样点数×采样间隔,计算更准确

x = np.linspace(0, lx, nl)
y = np.array(df['SOC_batt'])

# 传入采样间隔dt,直接得到「每小时周期数」为单位的频率
freqs = fftfreq(nl, d=dt)
mask = freqs > 0 

fft_vals = fft(y)
fft_theo = 2.0 * np.abs(fft_vals / nl)

# 计算周期(小时)
periods = 1 / freqs[mask]

plt.figure(2)
plt.plot(periods, fft_theo[mask], label='FFT amplitude vs period')
plt.xlabel('Period (hours)')
plt.ylabel('Amplitude')
plt.title('FFT Spectrum (Period Domain)')
plt.xscale('log')  # 对数轴更易区分小时/天/周等不同尺度的周期
plt.grid(True)
mpld3.display()

转换为更大时间单位

如果需要将周期转换为天、周、月,直接做单位换算即可:

  • 1天 = 24小时
  • 1周 = 168小时
  • 1月 ≈ 730小时(按30.4天计算)

比如24小时=1天,若后续发现对应频率0.000114的峰值,计算得周期为8760小时=365天(年周期)。


内容的提问来源于stack exchange,提问作者jenzoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:05:18