Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help with code, RMS, FFT
#1
Hi all,
maybe you can help me where is problem with this code.

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.fftpack import fft
import tkinter as tk
from tkinter import filedialog
 
#Prompt user for file
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(filetypes=[("Two Column CSV","*.csv")])
print(file_path)
 
#Load Data (assumes two column array
df = pd.read_csv(file_path,delimiter=',',header=None,names=["time","data"])
t = df["time"]
x = df["data"]
 
#Determine variables
N = np.int(np.prod(t.shape))#length of the array
N2 = 2**(N.bit_length()-1) #last power of 2
Fs = 1/(t[1]-t[0])  #sample rate (Hz)
T = 1/Fs;
print("# Samples:",N)
print("Next power of 2:",N2)
 
#Plot Data
plt.figure(1)  
plt.plot(t, x)
plt.xlabel('Time (seconds)')
plt.ylabel('Accel (g)')
plt.title(file_path)
plt.grid()
 
#Compute RMS and Plot
w = np.int(np.floor(Fs)); #width of the window for computing RMS
steps = np.int_(np.floor(N/w)); #Number of steps for RMS
t_RMS = np.zeros((steps,1)); #Create array for RMS time values
x_RMS = np.zeros((steps,1)); #Create array for RMS values
for i in range (0, steps):
    t_RMS[i] = np.mean(t[(i*w):((i+1)*w)]);
    x_RMS[i] = np.sqrt(np.mean(x[(i*w):((i+1)*w)]**2));  
plt.figure(2)  
plt.plot(t_RMS, x_RMS)
plt.xlabel('Time (seconds)')
plt.ylabel('RMS Accel (g)')
plt.title('RMS - ' + file_path)
plt.grid()
 
#Compute and Plot FFT
plt.figure(3)  
N = N2 #truncate array to the last power of 2
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
yf = fft(x, n = N)
plt.plot(xf, 2.0/N * np.abs(yf[0:np.int(N/2)]))
plt.grid()
plt.xlabel('Frequency (Hz)')
plt.ylabel('Accel (g)')
plt.title('FFT - ' + file_path)
plt.show()
I got this:

Error:
PS C:\Users\Frohr> conda activate base PS C:\Users\Frohr> & C:/ProgramData/Anaconda3/python.exe "c:/Users/Frohr/Můj disk/VIBRO GUARD/Python/FFT.py" C:/Users/Frohr/Desktop/piezo_100Hz.csv c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py:20: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations N = np.int(np.prod(t.shape))#length of the array # Samples: 300013 Next power of 2: 262144 c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py:36: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations w = np.int(np.floor(Fs)); #width of the window for computing RMS Traceback (most recent call last): File "c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py", line 54, in <module> yf = fft(x, n = N) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fftpack\basic.py", line 87, in fft return _pocketfft.fft(x, n, axis, None, overwrite_x) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fft\_pocketfft\basic.py", line 17, in c2c tmp = _asfarray(x) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fft\_pocketfft\helper.py", line 97, in _asfarray copy = not x.flags['ALIGNED'] File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\flags.py", line 98, in __getitem__ raise KeyError(key) KeyError: 'ALIGNED'
I added second / for N/2 in code. xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
and now another error on line 54...

Thank you for any advice.
Reply
#2
Check if the type of x is suitable for the call to fft() function.
Reply
#3
(Feb-19-2022, 05:07 PM)Gribouillis Wrote: Check if the type of x is suitable for the call to fft() function.

I think (obviously wrong) that x is array of float values. And FFT works with float array, or not?


Edit:
I use now x = np.array(df["data"]) and seems OK.
Reply
#4
Your problem was that you "think" instead of "know". The activity of Programming in Python is so effortless compared to other languages that it is easy to fall into the trap of "just trying things" instead of reading the doc's. This often works fine, but c'mon, you are using Pandas and SciPy and FFT. Maybe a little look at the documents is in order.

x is a Series. Dataframe[] returns a Series.

https://pandas.pydata.org/pandas-docs/st...exing.html

When you code didn't work you could set a breakpoint and check the type of x, or you could add code to print the type.
t = df["time"]
x = df["data"]
print(type(t), type(x))
Once you knew x was a series you would look at the documentation for a Pandas series and see that you can use "values" to get an ndarray containing the numeric values.

https://pandas.pydata.org/pandas-docs/st...das.Series
df = pandas.DataFrame({"x":(1.0, 2.0, 3.0, 4.0), "y":(0.0, 1.0, -1.0, 0.0)})
x = df["x"]
x_values = x.values
print("x", type(x), x)
print("x_values", type(x_values), x_values)
Output:
x <class 'pandas.core.series.Series'> 0 1.0 1 2.0 2 3.0 3 4.0 Name: x, dtype: float64 x_values <class 'numpy.ndarray'> [1. 2. 3. 4.]
Now that you know all about the data it is time to read about scipy fft.

https://docs.scipy.org/doc/scipy/referen...t.fft.html

Where is says
Quote:x: array_like
Input array, can be complex.
This is disappointingly unspecific, and a search of array_like in the scipy documentation yields too many results to be useful. But since you already know that passing a Series doesn't work and since Series has a property that is an ndarray, maybe ndarray is "array_like" enough.
Reply
#5
frohr Wrote:And FFT works with float array, or not?
Mathematically speaking yes, FFT works with an array of floats, but we are working with an implementation of something that appears externally like an array of floats. There can be several incompatible implementations of this naive concept. It means that the implemented FFT algorithm uses internal details of the data structure which we don't need to know. Our duty as programmers is to pass the correct data type as parameter.
Reply
#6
(Feb-19-2022, 04:58 PM)frohr Wrote: Hi all,
maybe you can help me where is problem with this code.

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.fftpack import fft
import tkinter as tk
from tkinter import filedialog
 
#Prompt user for file
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(filetypes=[("Two Column CSV","*.csv")])
print(file_path)
 
#Load Data (assumes two column array
df = pd.read_csv(file_path,delimiter=',',header=None,names=["time","data"])
t = df["time"]
x = df["data"]
 
#Determine variables
N = np.int(np.prod(t.shape))#length of the array
N2 = 2**(N.bit_length()-1) #last power of 2
Fs = 1/(t[1]-t[0])  #sample rate (Hz)
T = 1/Fs;
print("# Samples:",N)
print("Next power of 2:",N2)
 
#Plot Data
plt.figure(1)  
plt.plot(t, x)
plt.xlabel('Time (seconds)')
plt.ylabel('Accel (g)')
plt.title(file_path)
plt.grid()
 
#Compute RMS and Plot
w = np.int(np.floor(Fs)); #width of the window for computing RMS
steps = np.int_(np.floor(N/w)); #Number of steps for RMS
t_RMS = np.zeros((steps,1)); #Create array for RMS time values
x_RMS = np.zeros((steps,1)); #Create array for RMS values
for i in range (0, steps):
    t_RMS[i] = np.mean(t[(i*w):((i+1)*w)]);
    x_RMS[i] = np.sqrt(np.mean(x[(i*w):((i+1)*w)]**2));  
plt.figure(2)  
plt.plot(t_RMS, x_RMS)
plt.xlabel('Time (seconds)')
plt.ylabel('RMS Accel (g)')
plt.title('RMS - ' + file_path)
plt.grid()
 
#Compute and Plot FFT
plt.figure(3)  
N = N2 #truncate array to the last power of 2
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
yf = fft(x, n = N)
plt.plot(xf, 2.0/N * np.abs(yf[0:np.int(N/2)]))
plt.grid()
plt.xlabel('Frequency (Hz)')
plt.ylabel('Accel (g)')
plt.title('FFT - ' + file_path)
plt.show()
I got this:

Error:
PS C:\Users\Frohr> conda activate base PS C:\Users\Frohr> & C:/ProgramData/Anaconda3/python.exe "c:/Users/Frohr/Můj disk/VIBRO GUARD/Python/FFT.py" C:/Users/Frohr/Desktop/piezo_100Hz.csv c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py:20: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations N = np.int(np.prod(t.shape))#length of the array # Samples: 300013 Next power of 2: 262144 c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py:36: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations w = np.int(np.floor(Fs)); #width of the window for computing RMS Traceback (most recent call last): File "c:\Users\Frohr\Můj disk\VIBRO GUARD\Python\FFT.py", line 54, in <module> yf = fft(x, n = N) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fftpack\basic.py", line 87, in fft return _pocketfft.fft(x, n, axis, None, overwrite_x) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fft\_pocketfft\basic.py", line 17, in c2c tmp = _asfarray(x) File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\fft\_pocketfft\helper.py", line 97, in _asfarray copy = not x.flags['ALIGNED'] File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\flags.py", line 98, in __getitem__ raise KeyError(key) KeyError: 'ALIGNED'
I added second / for N/2 in code. xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
and now another error on line 54...

Thank you for any advice.
Reply
#7
Try using numpy.ascontiguousarray function to ensure that the input array is contiguous and aligned in memory
try: x1=np.ascontiguousarray(x)
then: f = fft(x1, n = N)
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020