使用python编写基于紫外-可见光谱的水质COD检测代码,读取三份excel文件,分别为10mg/L,15mg/L,20mg/L的标准溶液,excel文件中第一列为波长,第二列为透过率,对excel中的数据通过导数法进行预处理,得到一阶导数谱图,并绘制在同一个折线图上,再计算一阶导数谱的排列熵,通过排列熵算法进行特征波长的提取,最后,利用提取的特征波长处的特征值与对应的COD浓度进行PLS建模,得到COD的预测模型
时间: 2023-10-06 07:06:40 浏览: 68
好的,这是一个比较复杂的任务,需要使用多个第三方库来完成。以下是一个简单的示例代码,希望能够帮助你入门。
首先,我们需要导入需要的库:
```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter
from sklearn.cross_decomposition import PLSRegression
```
然后,我们可以定义一些常量和函数:
```python
# excel文件名
EXCEL_FILENAMES = ['10mg_L.xlsx', '15mg_L.xlsx', '20mg_L.xlsx']
# 特征波长数目
N_FEATURES = 5
def read_excel(filename):
"""读取excel文件"""
df = pd.read_excel(filename, header=None)
return df.iloc[:, :2].values
def preprocess(X):
"""对数据进行预处理"""
# 对透过率进行平滑处理
X[:, 1] = savgol_filter(X[:, 1], window_length=11, polyorder=2)
# 对透过率进行归一化处理
X[:, 1] = (X[:, 1] - np.min(X[:, 1])) / (np.max(X[:, 1]) - np.min(X[:, 1]))
# 计算一阶导数
dy = np.diff(X[:, 1])
dx = np.diff(X[:, 0])
dy_dx = dy / dx
# 对一阶导数进行平滑处理
dy_dx = savgol_filter(dy_dx, window_length=11, polyorder=2)
# 对一阶导数进行归一化处理
dy_dx = (dy_dx - np.min(dy_dx)) / (np.max(dy_dx) - np.min(dy_dx))
return dy_dx
def calculate_permutation_entropy(X):
"""计算排列熵"""
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
def permutation_entropy(X, m=3, delay=1):
n = X.shape[0]
permutations = np.zeros((factorial(m), n - (m - 1) * delay))
for i in range(n - (m - 1) * delay):
v = X[i:i + m * delay:delay]
idx = np.argsort(v)
for j, p in enumerate(idx):
permutations[j, i] = p
counts = np.unique(permutations, axis=1, return_counts=True)[1]
probabilities = counts / counts.sum()
return -np.sum(probabilities * np.log(probabilities))
return permutation_entropy(X)
def extract_features(X, n_features):
"""提取特征"""
fe = np.zeros((X.shape[1],))
for i in range(X.shape[1]):
fe[i] = calculate_permutation_entropy(X[:, i].reshape(-1, 1))
idx = np.argsort(fe)[-n_features:]
return X[:, idx]
def train_pls(X_train, y_train):
"""训练PLS模型"""
pls = PLSRegression(n_components=5)
pls.fit(X_train, y_train)
return pls
```
在这里,我们使用了`pandas`库来读取excel文件,并使用`numpy`和`matplotlib`库来对数据进行处理和可视化。我们还使用了`scipy`库中的`savgol_filter`函数来进行平滑处理,使用`sklearn`库中的`PLSRegression`模型来建立预测模型。
接下来,我们可以编写主函数:
```python
def main():
# 读取excel文件
Xs = []
ys = []
for filename in EXCEL_FILENAMES:
X = read_excel(filename)
y = float(filename.split('.')[0].replace('mg_L', ''))
Xs.append(X)
ys.append(y)
# 对数据进行预处理
Xs = [preprocess(X) for X in Xs]
# 提取特征
Xs = [extract_features(X, N_FEATURES) for X in Xs]
# 拼接数据
X = np.vstack(Xs)
y = np.array(ys * N_FEATURES)
# 训练PLS模型
pls = train_pls(X, y)
# 预测COD浓度
X_test = read_excel('test.xlsx')
X_test = preprocess(X_test)
X_test = extract_features(X_test, N_FEATURES)
y_pred = pls.predict(X_test.reshape(1, -1))[0]
print('预测COD浓度为:{:.2f}mg/L'.format(y_pred))
```
在这里,我们首先读取三个excel文件,并将它们的数据进行预处理和特征提取。然后,我们将它们拼接成一个大的数据集,并将每个样本的COD浓度作为目标变量。最后,我们使用拼接后的数据训练PLS模型,并使用模型来预测测试数据的COD浓度。
需要注意的是,这里我们假设每个excel文件中的数据都是按照波长递增的顺序排列的。如果实际数据不是这样的,需要先对数据进行排序。另外,这里的特征提取方法只是一种示例,实际应用中可能需要根据具体情况选择合适的特征提取方法。
阅读全文