光谱数据处理:1.特征波长优选的不同方法与Python实现

        首先,我们要理解为什么要对“光谱数据进行特征波长优选”以及这是在干嘛,光谱数据可以想象成一长串的彩色条纹,每种颜色对应一个波长,就像彩虹一样。这些颜色的条纹代表了从某种物质(比如植物、矿石或是食品)反射或透过光的特性。通过分析这些条纹,我们可以了解物质的很多信息,比如它是什么成分、有没有污染、熟度等等。

        但问题在于这长串的条纹实在太长了,里面有很多颜色,有的重要有的不重要。如果把每种颜色都当成一个线索来追,工作量会非常巨大,而且有很多无用功。所以我们需要找出那些最关键的颜色(也就是波长),这样我们就可以只关注这些颜色,提高我们的寻宝效率。

        特征波长优选,就是通过一系列数学方法和技巧,来确定哪些颜色的条纹(波长)最能帮助我们了解我们想要知道的信息。确定了这些关键的颜色条纹之后,我们在分析物质时就可以只看这些颜色,这样既省时又准确。

一、主成分分析法(Principal Component Analysis,PCA)

(1)原理详解

        假想你正在用一台相机从不同角度拍摄一座山。每张照片都提供了山的视角,但所有的照片都有重复的信息(都是同一座山),同时每个角度也显示了一些独特的细节。PCA的目标就是找出最好的几个角度,以最简洁的方式展现出山的最关键特征。

在数学上,PCA是这样实现的:

  1. 数据中心化: 首先,要将每个特征(如,每张照片的视角)调整为以零为中心,也就是说,我们需要从每个特征中减去它的平均值。这样做的目的是让PCA后续的计算更加方便,同时去除数据位置的影响,只保留数据形状的信息。

  2. 计算协方差矩阵: 接下来,我们计算数据的协方差矩阵。在我们的比喻中,协方差矩阵描述了不同角度之间如何变化,或者说这些角度是否会同时增加或减少。如果两个角度通常同时增减,它们就具有高协方差,意味着这两个角度信息重合得很多。

  3. 找出主成分: 现在,我们要找出主成分,也就是找到那些能够捕捉最多山的特征的“最好的角度”。数学上,这意味着我们要找到协方差矩阵的特征向量,并将它们按照对应特征值的大小排序。特征值越大,对应的特征向量就能捕捉越多的信息(变异性)。

  4. 降维: 最后,我们选择前几个最大的特征值和对应的特征向量。这些特征向量称为“主成分”,它们定义了新的坐标系,这个坐标系的坐标轴指向数据变化最大的方向。通过将原始数据投影到这些主成分上,我们可以用更少的维度来描述数据,同时保留最重要的信息。

        简而言之,PCA就像是找到了描述山的几张最有代表性的照片。每张照片(主成分)都尽可能多地包含了山的信息,且每张照片都提供了之前照片中没有的信息。通过这几张照片,我们可以用最少的数据捕捉到最关键的特征。

1)生成模拟光谱数据
def generate_spectral_data(samples, features):
    np.random.seed(0)
    return np.random.rand(samples, features)
  • generate_spectral_data 函数使用np.random.rand创建一个给定形状(samples行,features列)的数组,数组中的每个元素都是在[0,1)区间内均匀分布的随机浮点数。
  • 设置随机种子(np.random.seed(0))保证每次运行代码时生成的随机数是相同的,这有助于结果的可重复性。
2)PCA算法实现
def apply_pca(data, n_components):
    pca = PCA(n_components=n_components)
    principal_components = pca.fit_transform(data)
    return principal_components, pca.explained_variance_ratio_
  • apply_pca 函数利用scikit-learn中的PCA类来对输入数据data执行主成分分析。
  • n_components参数指定了PCA降维后保留的主成分数目。
  • fit_transform方法计算PCA并将数据转化为主成分空间,返回转换后的数据。
  • explained_variance_ratio_属性表示每个主成分解释的方差比例。

(2)完整代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA


# 生成模拟光谱数据
def generate_spectral_data(samples, features):
    np.random.seed(0)
    return np.random.rand(samples, features)


# 使用PCA进行特征提取
def apply_pca(data, n_components):
    pca = PCA(n_components=n_components)
    principal_components = pca.fit_transform(data)
    return principal_components, pca.explained_variance_ratio_


# 主函数
def main():
    # 模拟生成光谱数据,设定样本数和特征数
    samples = 100  # 样本数
    features = 200  # 特征数,即波长数
    spectral_data = generate_spectral_data(samples, features)

    # 应用PCA提取特征
    principal_components, explained_variance_ratio = apply_pca(spectral_data, n_components=2)

    # 绘制模拟光谱数据的前两个主成分
    plt.figure(figsize=(15, 5))
    plt.subplot(1, 2, 1)
    plt.scatter(principal_components[:, 0], principal_components[:, 1])
    plt.title("PCA - First two principal components")

    # 绘制解释方差比例
    plt.subplot(1, 2, 2)
    plt.bar(range(len(explained_variance_ratio)), explained_variance_ratio)
    plt.title("PCA - Explained variance ratio")

    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    main()

(3)运行结果

二、协同区间偏最小二乘法(SiPLS

(1)原理详解

        假设你是一名音乐制作人,你有一段复杂的音轨,里面包含了各种乐器的音频信号。你的目标是找出音轨中那些对整体音乐风格贡献最大的乐器组合。你不可能一次性听清每个乐器的影响,因此你需要一种方法来区分和评估每种乐器的重要性。

SiPLS的做法类似于这样一个过程:

  1. 划分区间: 就像你可能会把音轨分成多个部分来单独分析每个乐器一样,SiPLS首先将整个数据集(例如光谱数据)分成多个小的区间。这样做的目的是因为不同区间的数据(或者音乐中的乐器组合)可能会有不同的重要性。

  2. 区间选择: 接着,对于每个区间,SiPLS评估它们对于输出结果(可能是化学成分的浓度或者音乐风格的贡献)的影响。这个步骤类似于你听每个乐器段落并判断它对整体作品的贡献大小。

  3. 组合和构建模型: 根据这些区间的贡献,SiPLS会选择那些贡献最大的区间并将它们组合起来。这就像是你选取那些最能代表音乐风格的乐器组合,并将它们混合以形成一个完整的音轨。

  4. 优化和评估: 最后,SiPLS通过对这些选定区间的数据进行偏最小二乘回归分析来构建一个预测模型。在音乐制作中,你会尝试调整不同乐器的音量和效果来使整体作品听起来最好。同样,SiPLS调整模型参数来确保预测结果与实际结果尽可能接近。

总的来说,SiPLS的目的是在大量复杂数据中找到最有信息量的部分,然后只用这些部分来构建一个有效的模型。在光谱分析中,这意味着可以更准确地预测样本的性质,同时减少了计算量和噪声的影响。

1)生成模拟光谱数据
def generate_spectral_data(samples, features, noise_level=0.1):
    np.random.seed(0)
    # 生成波长
    wavelengths = np.linspace(400, 2500, features)
    # 生成光谱数据,基于某些波长的线性组合加噪声
    X = np.random.randn(samples, features) + np.sin(wavelengths) * 10
    # 生成响应变量,同样是波长的线性组合加噪声
    Y = np.dot(X, np.sin(wavelengths)) * 0.5 + np.random.randn(samples) * noise_level
    return X, Y, wavelengths
  • samples:数据集中的样本数量。
  • features:每个样本的特征数量,也可以看作是波长数。
  • noise_level:添加到数据中的噪声水平,用于更接近真实世界的情况。
  • X:模拟光谱数据矩阵。
  • Y:目标变量,通常是样本的某些特性,它与光谱数据有关联。
  • wavelengths:对应于光谱数据特征的波长值。
2)SiPLS算法实现
def SiPLS(X, Y, wavelengths, interval_length=10):
    n_intervals = X.shape[1] // interval_length
    scores = []
    
    for i in range(n_intervals):
        start = i * interval_length
        end = start + interval_length
        pls = PLSRegression(n_components=2)
        score = -np.mean(cross_val_score(pls, X[:, start:end], Y, cv=5, scoring='neg_mean_squared_error'))
        scores.append(score)
        
    # 返回每个区间的性能评分
    return np.array(scores), wavelengths[:n_intervals*interval_length:interval_length]
  • interval_length:决定了划分子区间的长度。
  • n_intervals:根据给定的光谱特征数和区间长度计算总共可以划分的区间数。
  • scores:记录每个区间PLS模型的均方误差(MSE)分数列表。
  • 循环遍历每个区间,对每个子区间执行PLS回归,并通过交叉验证计算MSE分数。
  • 返回每个区间的MSE分数和对应的波长值。

(2)完整代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_val_score

# 生成模拟光谱数据
def generate_spectral_data(samples, features, noise_level=0.1):
    np.random.seed(0)
    # 生成波长
    wavelengths = np.linspace(400, 2500, features)
    # 生成光谱数据,基于某些波长的线性组合加噪声
    X = np.random.randn(samples, features) + np.sin(wavelengths) * 10
    # 生成响应变量,同样是波长的线性组合加噪声
    Y = np.dot(X, np.sin(wavelengths)) * 0.5 + np.random.randn(samples) * noise_level
    return X, Y, wavelengths

# SiPLS算法
def SiPLS(X, Y, wavelengths, interval_length=10):
    n_intervals = X.shape[1] // interval_length
    scores = []
    
    for i in range(n_intervals):
        start = i * interval_length
        end = start + interval_length
        pls = PLSRegression(n_components=2)
        score = -np.mean(cross_val_score(pls, X[:, start:end], Y, cv=5, scoring='neg_mean_squared_error'))
        scores.append(score)
        
    # 返回每个区间的性能评分
    return np.array(scores), wavelengths[:n_intervals*interval_length:interval_length]

# 主函数
def main():
    samples = 100
    features = 200
    X, Y, wavelengths = generate_spectral_data(samples, features)
    
    # 应用SiPLS
    scores, selected_wavelengths = SiPLS(X, Y, wavelengths)
    
    # 绘图展示原始数据
    plt.figure(figsize=(15, 6))
    plt.subplot(2, 1, 1)
    plt.plot(wavelengths, X.T, color='grey', alpha=0.5)
    plt.title("Simulated Spectral Data")
    
    # 绘图展示SiPLS区间评分
    plt.subplot(2, 1, 2)
    plt.plot(selected_wavelengths, scores, marker='o')
    plt.xlabel('Wavelength (nm)')
    plt.ylabel('MSE Score')
    plt.title('SiPLS Interval Scores')
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    main()

(3)运行结果

        由图可通过对比不同子区间的MSE分数,来选择最佳特征波长进行后续分析。

三、连续投影算法(Successive Projections Algorithm,SPA

(1)原理详解

        想象一下,你有一个乐队,每个乐器都发出不同的声音。如果要为一首曲子选择最合适的乐器组合,你会尝试找出哪些乐器最能代表歌曲的核心旋律和节奏,同时确保它们听起来不会混在一起,即每个乐器的声音都是清晰和独特的。

SPA的工作原理即为以下几个步骤:

  1. 开始时,所有乐器都可选择: SPA开始时,所有的变量(在光谱数据中即为所有波长)都是可选择的。在乐队的比喻中,这就像是所有乐器都准备好了,等待被选中加入曲目。

  2. 选择第一个乐器: 首先,SPA会从所有乐器中选择一个最能代表曲目的乐器。在数学上,这相当于从所有变量中选择一个与响应变量(可能是化学成分的浓度)关联最紧密的变量。

  3. 寻找与已选乐器不同的乐器: 接下来,SPA会在剩下的乐器中寻找一个与已选乐器尽可能不同的乐器。数学上,这意味着寻找一个与已选变量正交(或者说相关性最小)的变量。这样可以确保新选择的变量能提供一些新信息,而不是重复之前已选择的变量的信息。

  4. 迭代选择: SPA会重复上述过程,每次都选出一个与当前已选集合正交的新变量。这就像是一个个挑选乐器,确保每个新增的乐器都能带来不同的音色,从而丰富整首歌曲。

  5. 终止条件: 这个过程会一直进行,直到达到预先设定的乐器数量(或者在光谱数据分析中的变量数量)或者进一步添加乐器(变量)不再使得曲目(模型)有显著提升。

        通过SPA,你最终会得到一个由互相独立的乐器(变量)组成的乐队(数据子集),它们合在一起能够很好地演奏出一首曲子(构建一个有效的预测模型)而不会有太多的噪音(不必要的信息或多余的变量)干扰听众(模型的性能)。

        所以,SPA帮助你从大量的可能选项中挑选出最有代表性且互不干扰的一小部分,用以构建一个既简洁又有效的模型。

SPA算法的实现
def successive_projections_algorithm(X, num_variables):
    num_samples, num_features = X.shape
    selected_variables = []
    P = np.eye(num_samples)
    for i in range(num_variables):
        var_projections = np.dot(X.T, P).T
        var_norms = np.sum(var_projections**2, axis=0)
        next_var = np.argmax(var_norms)
        selected_variables.append(next_var)
        xi = X[:, [next_var]]
        P = P - np.dot(np.dot(P, xi), np.dot(xi.T, P)) / np.dot(np.dot(xi.T, P), xi)
    return selected_variables
  • 函数successive_projections_algorithm(X, num_variables)接受输入数据X(假设为光谱数据)和一个整数num_variables,表示要选择的变量数量。
  • 算法初始化一个单位矩阵P作为投影矩阵。
  • 在每次迭代中:
    • 计算当前残差矩阵XP的乘积,得到各变量的投影。
    • 计算每个变量投影的范数(即投影向量的平方和),选择范数最大的变量,因为它包含最多的残差信息。
    • 更新所选变量的索引列表selected_variables
    • 使用更新后的投影矩阵P计算新的残差矩阵。
    • 最后返回选择的变量索引列表。

(2)完整代码

import numpy as np
import matplotlib.pyplot as plt

def successive_projections_algorithm(X, num_variables):
    num_samples, num_features = X.shape
    selected_variables = []
    P = np.eye(num_samples)
    for i in range(num_variables):
        var_projections = np.dot(X.T, P).T
        var_norms = np.sum(var_projections**2, axis=0)
        next_var = np.argmax(var_norms)
        selected_variables.append(next_var)
        xi = X[:, [next_var]]
        P = P - np.dot(np.dot(P, xi), np.dot(xi.T, P)) / np.dot(np.dot(xi.T, P), xi)
    return selected_variables

# 模拟一些数据作为示例
np.random.seed(0)
num_samples = 200
num_features = 100
X = np.random.rand(num_samples, num_features)  # 模拟的光谱数据

# 使用SPA选择特征
num_selected_variables = 10  # 你希望选择的特征数量
selected_wavelengths = successive_projections_algorithm(X, num_selected_variables)

# 绘图以显示原始光谱数据和选定的特征波长
average_spectrum = np.mean(X, axis=0)
wavelengths = np.arange(num_features)  # 假设波长是连续的整数值

plt.figure(figsize=(12, 6))
plt.plot(wavelengths, average_spectrum, label='Average Spectrum')
plt.scatter(wavelengths[selected_wavelengths], average_spectrum[selected_wavelengths], color='red', label='Selected Wavelengths')
plt.xlabel('Wavelength')
plt.ylabel('Intensity')
plt.title('Spectral Data with Selected Features by SPA')
plt.legend()
plt.show()

(3)运行结果

四、竞争自适应重采样算法(Competive Adaptive Reweighted Sampling ,CARS

(1)原理详解

        想象一下,你是一个厨师,面前放着各种各样的食材。你的任务是从中选择出最合适的几种来制作一道美味的菜肴。但是,有一个挑战:你的菜板空间有限,不能同时准备太多的食材。

        这里是你的策略:

  1. 先试一小部分:你首先随机挑一小撮食材做个样品菜,看看效果怎样。

  2. 评估每种食材:根据样品菜的口感,你评估每种食材的贡献大小,哪些食材让菜更美味,哪些没有太大帮助。

  3. 淘汰一些食材:你决定淘汰掉那些看起来不怎么影响味道的食材,因为你的空间有限,需要给更有潜力的食材留下位置。

  4. 调整食材比重:根据你对每种食材的评估,你决定调整它们在菜中的比重,比如增加某些食材的用量,减少或淘汰另一些。

  5. 重复过程:你不断重复这一过程,每次用不同的食材组合做样品菜,评估,淘汰,直到找到那个完美的配方,即最能提升你菜品口味的食材组合。

  6. 最终结果:最后,你得到了一个既不过多也不过少,每种食材都能发挥其最佳效果的食材组合,这就是你的拿手好菜。

        将这个比喻转换为 CARS 算法的话,这些食材就像是你要分析的数据中的特征(如光谱数据中的波长),而美味的菜肴就像是一个强大的预测模型,你希望只用最有信息量的特征来做出预测。CARS 通过一个迭代的过程,不断地选择和调整特征,以确保最终模型的精确度和可解释性。就像厨师通过尝试和调整来找到最好的食材组合一样。

利用 SelectKBest 进行特征选择
selector = SelectKBest(score_func=f_regression, k=10)
X_selected = selector.fit_transform(X, y)

创建一个SelectKBest对象,用于特征选择。score_func参数设置为f_regression,这意味着选择特征的依据是每个特征对目标变量的 F-统计量。参数k=10指定我们希望选择的特征数量。

fit_transform方法将选择操作应用于数据X和目标y,结果是筛选后的数据X_selected,它只包含了我们希望保留的那些最佳特征。

(2)完整代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.feature_selection import SelectKBest, f_regression

# 假设 X 是模拟的光谱数据,y 是相应模拟的目标变量
np.random.seed(0)
X = np.random.rand(100, 200)  # 100个样本,200个波长点
y = np.random.rand(100)       # 100个样本的目标值

# 使用 SelectKBest 进行特征选择,这里使用的是 f_regression 方法
# f_regression 是用于回归任务的特征选择函数,它不是CARS算法
selector = SelectKBest(score_func=f_regression, k=10)
X_selected = selector.fit_transform(X, y)

# 绘制原始数据和经过特征选择后的数据
plt.figure(figsize=(14, 6))

# 绘制原始数据
plt.subplot(1, 2, 1)
plt.imshow(X.T, aspect='auto')
plt.colorbar()
plt.title('Original Spectra Data')

# 绘制特征选择后的数据
plt.subplot(1, 2, 2)
selected_features = selector.get_support(indices=True)
selected_spectra = X[:, selected_features]
plt.imshow(selected_spectra.T, aspect='auto')
plt.colorbar()
plt.title('Selected Features')

plt.show()

(3)运行结果

五、随机蛙跳算法(Random-Frog

(1)原理详解

        想象你在一个巨大的草地上寻找宝藏,草地上有很多可能藏有宝藏的地点,但你没有地图,所以不知道宝藏确切在哪儿。

        这就是随机蛙跳算法的情况,其中宝藏相当于对我们很重要的信息或特征(就像在光谱数据中找到最重要的波长点),而草地的每个地点代表数据集中的一个特征。

        现在,随机蛙跳算法的过程大概是这样的:

  1. 随机选择:你闭上眼睛,随机地跳到草地上的某个点,就好像是“蛙跳”一样。

  2. 挖掘尝试:在这个点上,你用铲子挖挖看,看能不能找到宝藏。

  3. 记录结果:如果你觉得这个点下面可能有宝藏,你就在地图上做个标记,这样你就知道这个地方值得以后再来挖掘。

  4. 重复过程:你重复闭眼随机跳跃和挖掘的过程很多次。

  5. 分析结果:最后,你打开眼睛,看看哪些地方被标记了很多次。这些地方很可能就是藏宝的热点,因为你多次随机挖掘都觉得那里可能有宝藏。

  6. 做出判断:最后,你决定专注于那些被反复标记的地点进行深入挖掘,因为这样做找到宝藏的可能性最大。

        用这个比喻来理解,随机蛙跳算法通过反复随机选择一些特征,并评估它们对结果的影响(有没有“挖到宝藏”),然后总结哪些特征最有可能是我们寻找的“宝藏”。这种方法不需要预先知道哪里有宝藏,而是通过重复随机尝试和评估来找到最好的线索。

def random_frog(X, y, num_selected_features, num_iterations=100):
    # 保存特征的重要性分数
    feature_importances = np.zeros(X.shape[1])
    
    # 随机蛙跳迭代过程
    for _ in range(num_iterations):
        # 选择一个随机特征子集
        selected_features = np.random.choice(X.shape[1], num_selected_features, replace=False)
        
        # 创建一个随机森林分类器
        model = RandomForestClassifier(n_estimators=10, random_state=0)
        
        # 使用选定的特征和随机森林进行训练
        model.fit(X[:, selected_features], y)
        
        # 更新特征的重要性分数
        feature_importances[selected_features] += model.feature_importances_
    
    # 根据重要性分数选择最重要的特征
    important_features = np.argsort(feature_importances)[-num_selected_features:]
    
    return important_features

        该函数使用了一个简化的随机蛙跳过程来选择特征。在这个过程中,我们在每个迭代步骤中随机选择一个特征子集,并用随机森林算法训练一个模型,然后基于模型输出的特征重要性分数来更新这些特征的总重要性评分。在多次迭代之后,我们选择那些具有最高累积重要性分数的特征。

(2)完整代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier

# 假设光谱数据集 X 和对应的类别标签 y
# 生成一些示例数据作为光谱数据
np.random.seed(0)
X = np.random.rand(100, 200)  # 100个样本,200个波长特征
y = np.random.randint(0, 2, 100)  # 100个样本的类别标签(0或1)


# 定义一个简化的 Random Frog 方法
def random_frog(X, y, num_selected_features, num_iterations=100):
    # 保存特征的重要性分数
    feature_importances = np.zeros(X.shape[1])

    # 随机蛙跳迭代过程
    for _ in range(num_iterations):
        # 选择一个随机特征子集
        selected_features = np.random.choice(X.shape[1], num_selected_features, replace=False)

        # 创建一个随机森林分类器
        model = RandomForestClassifier(n_estimators=10, random_state=0)

        # 使用选定的特征和随机森林进行训练
        model.fit(X[:, selected_features], y)

        # 更新特征的重要性分数
        feature_importances[selected_features] += model.feature_importances_

    # 根据重要性分数选择最重要的特征
    important_features = np.argsort(feature_importances)[-num_selected_features:]

    return important_features


# 使用随机蛙跳方法选择特征
selected_features = random_frog(X, y, num_selected_features=20)

# 绘制原始数据
plt.figure(figsize=(15, 5))
plt.subplot(1, 2, 1)
plt.imshow(X.T, aspect='auto', cmap='viridis')
plt.colorbar()
plt.title('Original Spectral Data')

# 绘制经过特征选择后的数据
plt.subplot(1, 2, 2)
selected_data = X[:, selected_features]
plt.imshow(selected_data.T, aspect='auto', cmap='viridis')
plt.colorbar()
plt.title('Selected Features')

plt.tight_layout()
plt.show()

(3)运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/412017.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计网自顶向下:网络应用层【Web应用与HTTP协议】

目录 Web应用Web页URLWorld Wide Web 超文本传输协议——HTTP超文本C/S结构报文请求报文响应报文HTTP响应状态码try:在命令行里手工给web服务器发送请求 http连接的两种类型非持久(http1.0)持久(http1.1)▷ 流水线▷ 非…

【自然语言处理三-自注意self attention】

自然语言处理三-自注意力 self attention 自注意力是什么?自注意力模型出现的原因是什么?词性标注问题解决方法1-扩展window,引用上下文解决方法2-运用seq2seq架构新问题来了:参数量增加、无法并行的顽疾 自注意力self attention模…

C++ list详解以及模拟实现

目录 1.list的使用 1.1list的定义 1.2list的使用 1.3list iterator使用 1.4list capacity 1.5list element access 1.6list增删查改 2.list迭代器失效问题 3.list的模拟实现 1.list的使用 1.1list的定义 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容…

水印相机小程序源码

水印相机前端源码,本程序无需后端,前端直接导入即可,没有添加流量主功能,大家开通后自行添加 源码搜索:源码软件库 注意小程序后台的隐私权限设置,前端需要授权才可使用 真实时间地址拍照记录&#xff0c…

alembic

alembic是sqlalchemy的作者开发的。 用来做OMR模型与数据库的迁移与映射。 第一个,alembic的所有命令都是以alembic开头 第二,alembic的迁移文件也是通过版本进行控制的。首先,通过pip install alembic进行安装。以下将解释alembic的用法 方…

从管易云·奇门到金蝶云星空通过接口配置打通数据

从管易云奇门到金蝶云星空通过接口配置打通数据 对接源平台:管易云奇门 管易云是金蝶旗下专注提供电商企业管理软件服务的子品牌,先后开发了C-ERP、EC-OMS、EC-WMS、E店管家、BBC、B2B、B2C商城网站建设等产品和服务,涵盖电商业务全流程。 目标系统:金蝶…

ZYNQ:串口-CAN协议转换

前言 目前已经实现zynq的PS-CAN和PL-CAN功能。串口-CAN协议转换是实现以太网-CAN功能的过渡,通过这个流程能够减少后期以太网工程出现问题的频率。阶段性功能目标如下: 实现数据在CAN调试助手和串口调试助手之间的来回转换,从而了解中断机制…

Vue前端对请假模块——请假开始时间和请假结束时间的校验处理

开发背景:Vueelement组件开发 业务需求:用户提交请假申请单,请假申请的业务逻辑处理 实现:用户选择开始时间需要大于本地时间,不得大于请假结束时间,请假时长根据每日工作时间实现累加计算 页面布局 在前…

【Excel PDF 系列】EasyExcel + iText 库

你知道的越多,你不知道的越多 点赞再看,养成习惯 如果您有疑问或者见解,欢迎指教: 企鹅:869192208 文章目录 前言转换前后效果引入 pom 配置代码实现定义 ExcelDataVo 对象主方法EasyExcel 监听器 前言 最近遇到生成 …

SQL进阶(三):Join 小技巧:提升数据的处理速度

复杂数据结构处理:Join 小技巧:提升数据的处理速度 本文是在原本sql闯关的基础上总结得来,加入了自己的理解以及疑问解答(by GPT4) 原活动链接 用到的数据:链接 提取码:l03e 目录 1. 课前小问…

动态规划之第 N 个泰波那契数/三步问题【leetCode】【算法】

动态规划动态规划之第 N 个泰波那契数/三步问题 动态规划LeetCode题目第 N 个泰波那契数求解1求解2(滚动数组) 三步问题求解1求解2(滚动数组) 动态规划 如果问题是由重叠的子问题构成的,那就可以用动态规划&#xff08…

JSON简介以及如何在Python中使用JSON

什么是JSON? JSON是"JavaScript Object Notation"的简称,是一种数据交换格式 JSON格式 假设我们有一个对象,这个对象有两个属性:“name”跟“age”。 在JSON中是这样表达的: { "name":"男孩…

【 C++ 】闭散列哈希表的模拟实现

哈希节点状态 我们都很清楚数组里的每一个值无非三种状态: 如果某下标没有值,则代表空EMPTY。如果有值在代表存在EXIST。如果此位置的值被删掉了,则表示为DELETE。 而这三种状态我们可以借助enum枚举来帮助我们表示数组里每个位置的状态。…

RK3568平台开发系列讲解(基础篇)如何快速学习一套 Linux开发板源码

🚀返回专栏总目录 文章目录 一、基础代码二、驱动代码沉淀、分享、成长,让自己和他人都能有所收获!😄 拿到一份源码和一块评估板,如何快速找到与这块板相关的源码,是很多研发人员都曾遇到过的问题。如果对内核源码结构有大概了解,要完成这些事情也不难,通常可按照基础…

ASLR 和 PIE

前言 ASLR(Address Space Layout Randomization,地址空间随机化)是一种内存攻击缓解技术,是一种操作系统用来抵御缓冲区溢出攻击的内存保护机制。这种技术使得系统上运行的进程的内存地址无法被预测,使得与这些进程有…

高性能 Kafka 及常见面试题

Kafka 是一种分布式的,基于发布/订阅的消息系统,原本开发自 LinkedIn,用作 LinkedIn 的事件流(Event Stream)和运营数据处理管道(Pipeline)的基础。 基础原理详解可见 Kafka 基本架构及原理 基础…

事件循环解析

浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后&…

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用 1. 前言1.1 关于Excel的一般导出2.2 关于easyexcel的根据模版导出 2. 先看效果2.1 模版2.2 效果 3. 代码实现(核心代码)3.1 项目代码结构3.2 静态填充例子…

全域增长方法论:帮助品牌实现科学经营,助力长效生意增长

前两年由于疫情反复、供给需求收缩等条件制约,品牌业务均受到不同程度的影响。以双十一和618电商大促为例,就相比往年颇显“惨淡”,大多品牌营销都无法达到理想预期。 随着市场环境不断开放,2023年营销行业开始从低迷期走上了高速…

RPA中国 x UiPath | 第六届RPA极客挑战赛,3月16日上海开赛!

随着人工智能技术的不断进步以及数字化转型的深入,企业对于高效、精准、自动化的业务流程需求日益迫切。RPA技术作为连接人类工作与机器操作的桥梁,正逐渐从规则驱动发展为智能决策的助手。 由RPA中国联合UiPath共同主办的【第六届RPA极客挑战赛】将于2…