C# pythonnet(3)_Butter-worth低通滤波
Python代码如下
import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy import signal def lowpass_Butterworth(sig,fs,filter_cutoff=None,order=8,axis=0): ''' Butter-worth低通滤波 Inputs: sig --- numpy array, 输入时间序列数据 fs --- int, 采样率 filter_cutoff --- float, 截断频率,滤掉高于此频率的成分 order --- int, 滤波器阶次 axis --- int, 在sig的哪个轴上施加滤波 ''' if not filter_cutoff: filter_cutoff=fs/4 b,a = signal.butter(order,filter_cutoff / (fs/2),'low') sig = signal.filtfilt(b,a,sig,axis=axis) return sig # 读取数据 data = pd.read_csv('clean_data_row6.csv') data = np.array(data) dataLen = len(data) # Butter-worth低通滤波 fs=50 #采样频率 filter_cutoff=10 #截断频率 axis=0 #时间轴所在维度 # use_downsamping=True #是否降采样 calcData = lowpass_Butterworth(data, fs, filter_cutoff) calcData = np.array(calcData) calcDataLen = len(calcData) # 绘制原始数据图和Butter-worth低通滤波图 # 原始数据图 plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.plot(np.arange(dataLen), np.abs(data)) plt.title('Original Datas') # Butter-worth低通滤波图 plt.subplot(1, 2, 2) plt.plot(np.arange(calcDataLen), np.abs(calcData)) plt.title('Lowpass Butterworth Datas') plt.tight_layout() plt.show()
下面我们修改成C#代码
创建控制台程序,Nuget安装 CsvHelper 和 pythonnet
public class Program { const string PathToPythonDir = "D:\\Python311"; const string DllOfPython = "python311.dll"; static void Main(string[] args) { // Butter-worth低通滤波 ButterworthLowpass(); } /// <summary> /// Butter-worth低通滤波 /// </summary> static void ButterworthLowpass(int fs = 250, double filterCutoff = 50, int axis = 0, int order = 8) { try { Runtime.PythonDLL = Path.Combine(PathToPythonDir, DllOfPython); PythonEngine.Initialize(); using (Py.GIL()) { dynamic pd = Py.Import("pandas"); dynamic np = Py.Import("numpy"); dynamic plt = Py.Import("matplotlib.pyplot"); dynamic signal = Py.Import("scipy.signal"); dynamic data = pd.read_csv("clean_data_row.csv"); int listLength = data.__len__(); double wn = filterCutoff / (fs / 2.0); PyTuple baTuple = signal.butter(order, wn, "low"); dynamic b = baTuple[0]; dynamic a = baTuple[1]; PyObject calcData = signal.filtfilt(b, a, data, axis: axis, padlen: listLength - 1); int calcLength = data.__len__(); double[][] calcDataArray = calcData.As<dynamic[]>().Select(s => (double[])s.As<double[]>()).ToArray(); plt.figure(figsize: new dynamic[] { 12, 6 }); // 原始数据 plt.subplot(1, 2, 1); plt.plot(np.arange(listLength), data); plt.title("Original Datas"); // 低通滤波 plt.subplot(1, 2, 2); plt.plot(np.arange(calcLength), calcData); plt.title("Butterworth Lowpas Datas"); // 布局调整,防止重叠 plt.tight_layout(); // 显示图表 plt.show(); } } catch (Exception e) { Console.WriteLine("报错了:" + e.Message + "\r\n" + e.StackTrace); } } /// <summary> /// 读取CSV数据 /// </summary> /// <param name="filePath">文件路径</param> /// <returns>文件中数据集合,都是double类型</returns> static List<double[]> ReadCsvWithCsvHelper(string filePath) { using (var reader = new StreamReader(filePath)) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { var result = new List<double[]>(); // 如果你的CSV文件有标题行,可以调用ReadHeader来读取它们 csv.Read(); csv.ReadHeader(); while (csv.Read()) { result.Add(new double[] { csv.GetField<double>(0), csv.GetField<double>(1), csv.GetField<double>(2), }); } return result; } } }
以下是运行后结果,左边是原始数据折线图,右边是执行Butter-worth低通滤波后数据折线图
源代码:https://gitee.com/Karl_Albright/csharp-demo/tree/master/PythonnetDemo/PythonnetButterworth