Python中电机振动信号FFT分析异常求助
Hey there, let's work through why your FFT spectrum is coming out abnormal and fix it up. First, let's recap your setup to make sure we're on the same page:
- Dataset: 178,432 acceleration samples (unit: g)
- Sampling rate: 25000 Hz
- Motor rotational speed: 1500 rpm = 25 Hz (this is the fundamental frequency we should expect to see in the spectrum)
Looking at your code, there are a few key issues that are likely causing the weird spectrum. Let's break them down and fix each one:
1. Incorrect Data Loading & Shape Handling
Your current code uses nor.values directly, which might pull in multiple columns if your CSV has headers or extra metadata. Also, nor.size counts all elements in the DataFrame (rows × columns), which is wrong if you only have a single column of vibration data. We need to make sure we're only grabbing the actual vibration signal column.
2. Unscaled FFT Output
The raw FFT result's amplitude doesn't directly map to your original signal's units (g). We need to scale it properly to get meaningful amplitude values.
3. Plotting Symmetric FFT Data (Including Negative Frequencies)
For real-world signals like vibration data, the FFT output is symmetric around 0 Hz. Plotting the full spectrum includes redundant negative frequencies, which clutters the plot and makes it hard to see relevant peaks.
Fixed Code with Explanations
import scipy.fftpack import numpy as np import pandas as pd import matplotlib.pyplot as plt # Load the data - adjust header based on your CSV structure # If your CSV has no header row, use header=None; if first row is header, use header=0 nor = pd.read_csv('normal.csv', header=1) # Extract the vibration signal - assuming it's in the first column # Run print(nor.head()) to confirm the column name/index if unsure y = nor.iloc[:, 0].values # Grab only the first column's values N = len(y) # Correct number of samples (not total elements in DataFrame) T = 1.0 / 25000.0 # Sampling interval # Apply a Hanning window to reduce spectral leakage (optional but highly recommended) window = np.hanning(N) y_windowed = y * window # Compute FFT and scale the amplitude to match original signal units yf = scipy.fftpack.fft(y_windowed) # Scale: divide by N, double for positive frequencies (exclude DC component) yf_scaled = 2.0 / N * np.abs(yf[:N//2]) # Get positive frequencies only (up to Nyquist frequency: Fs/2 = 12500 Hz) xf = scipy.fftpack.fftfreq(N, d=T)[:N//2] # Plot the cleaned spectrum fig, ax = plt.subplots(figsize=(10, 6)) ax.plot(xf, yf_scaled) ax.set_xlabel('Frequency (Hz)') ax.set_ylabel('Amplitude (g)') ax.set_title('Motor Vibration FFT Spectrum') ax.grid(True) # Highlight the motor's fundamental rotational frequency for quick reference ax.axvline(x=25, color='r', linestyle='--', label='25 Hz (Motor Rotational Frequency)') ax.legend() plt.show()
Additional Tips to Verify & Improve
- Check Your Data First: Run
print(nor.head())andprint(nor.shape)to confirm you're loading the data correctly. If your CSV has extra columns (like timestamps), make sure you're only using the vibration acceleration column. - Spectral Leakage Fix: The Hanning window we added helps reduce "leakage" where energy from a sharp peak spreads across adjacent frequency bins. This is critical if your signal isn't perfectly periodic in the sampled window.
- Look for Expected Peaks: After fixing the code, you should see a clear peak at 25 Hz (motor rotation), plus possible harmonics (50 Hz, 75 Hz, etc.) depending on the motor's condition.
内容的提问来源于stack exchange,提问作者 yang

