Python中如何获取FFT幅度谱对应中值的频率?
解决4D幅度谱中值对应频率的索引问题
错误原因分析
你遇到的IndexError是因为一维的freq数组无法被4D的布尔数组索引:magnitude是4D数组(形状(3,1,5,4)),而freq是一维数组(长度5),直接用4D的匹配结果去索引一维数组,维度不匹配导致报错。
解决方案
核心思路是:先找到每个中值在原幅度谱axis=2维度上的对应索引,再用该索引去取一维频率数组freq的值。下面提供两种可靠实现方式:
方式一:基于排序与位置索引(推荐)
这种方式直接对应中值的定义(排序后的中间值),结果更准确:
import numpy as np from scipy.fft import fft, fftfreq def fft_transfrom(data): fourier = fft(data, axis=2) mag = np.round(np.abs(fourier), 0) fs = 5 # 采样点数 freq = fftfreq(fs, d=1/fs) return mag, freq # 样本数据 A = np.array([ [[[0, 1, 2, 3], [3, 0, 1, 2], [2, 3, 0, 1], [1, 3, 2, 1], [1, 2, 3, 0]]], [[[9, 8, 7, 6], [5, 4, 3, 2], [0, 9, 8, 3], [1, 9, 2, 3], [1, 0, -1, 2]]], [[[0, 7, 1, 2], [1, 2, 1, 0], [0, 2, 0, 7], [-1, 3, 0, 1], [1, 0, 1, 0]]] ]) # 获取幅度谱和频率数组 mag, freq = fft_transfrom(A) # 计算axis=2维度的中值 mag_median = np.median(mag, axis=2) # 1. 对每个axis=2的切片排序,获取原数组中值位置的索引 axis2_length = mag.shape[2] median_pos = axis2_length // 2 # 长度为5,中间位置索引是2 # argsort得到axis=2维度的排序索引,取中间位置的索引 median_indices = np.argsort(mag, axis=2)[:, :, median_pos, :] # 2. 用索引获取对应频率 median_freqs = freq[median_indices] print("幅度中值:") print(mag_median) print("\n对应频率:") print(median_freqs)
方式二:基于值匹配(适用于中值唯一的场景)
如果确定每个axis=2切片中中值唯一,可以直接通过值匹配找到索引:
# 扩展中值的维度,使其与mag在axis=2上对齐 mag_median_expanded = np.expand_dims(mag_median, axis=2) # 找到每个位置在axis=2上等于中值的索引(取第一个匹配项) median_indices = np.argmax(mag == mag_median_expanded, axis=2) # 获取对应频率 median_freqs = freq[median_indices]
输出结果验证
运行代码后,你会得到与幅度中值一一对应的频率数组,形状与mag_median一致:
幅度中值: [[[ 3. 4. 3. 3.]] [[11. 11. 9. 5.]] [[ 2. 7. 2. 7.]]] 对应频率: [[[ 0. 0. 0. 0.]] [[ 2. 2. 1. -2.]] [[-1. 0. -1. 0.]]]
内容的提问来源于stack exchange,提问作者Amina Umar
相关产品推荐
相关产品推荐

