C-MAPSS数据集可视化与预处理:MATLAB完整代码解析,发动机寿命预测必学数据集!

深入解析C-MAPSS数据集

C-MAPSS数据集由NASA为研究航空发动机故障预测而开发的。备受发动机寿命预测科研儿的青睐,在各种顶级期刊频繁出现。因其数据比较完整,整理较为方便,且数据的拟合难度较高,是检验深度学习算法性能的试金石。本期推文采用MATLAB代码实现对该数据的深度剖析。


一、数据集概览

C-MAPSS(Commercial Modular Aero-Propulsion System Simulation)是航空发动机退化仿真数据集,官方数据获取链接:https://data.nasa.gov/dataset/cmapss-jet-engine-simulated-data  

C-MAPSS数据集由四个独立子集(FD001-FD004)构成,每个子集针对不同的工况与故障场景设计,具体配置如下:

子集训练样本数测试样本数运行条件故障模式

FD001

100

100

单一工况

高压压气机(HPC)退化

FD002

260

259

六种混合工况

HPC退化

FD003

100

100

单一工况

HPC+风扇复合退化

FD004

248

249

六种混合工况

HPC+风扇复合退化

FD001/FD003聚焦单一工况,FD002/FD004模拟多工况切换的复杂场景。FD003/FD004额外引入风扇退化问题。

以FD001为例,训练轨迹指每台发动机在其运行周期内的时间序列数据。每个训练轨迹对应于一台发动机的运行数据。100 条训练轨迹就是 100 台发动机, 每台发动机的初始磨损和制造工艺是不同的,这些差异被视为正常情况,而不是故障条件。

数据集中包含21个传感器记录的数值和不同operational setting,这些setting对发动机性能有显著影响。

  • C-MAPSS 数据集的物理含义

  • 传感器分布如图:

    在训练集中,模拟发动机从健康状态到故障状态的完整退化过程;而在测试集中,提供部分发动机的衰退轨迹,数据在故障发生之前随机截断(即未到真正发生故障的时间点)。测试模型根据当前的传感器值推断剩余使用寿命。

二、手撕MATLAB代码深度分析数据

读取C-MAPSS数据

% 数据加载核心代码
clear; clc; close all;
addpath(genpath(pwd)); % 添加当前目录到路径

% 定义读取数据的函数
function data = get_data(file_name)
    file_path = fullfile('C-MAPSS-Data\', file_name);
    if exist(file_path, 'file') == 2
        data = readtable(file_path, 'Delimiter', ' ', 'MultipleDelimsAsOne', true, ...
            'ReadVariableNames', false,'HeaderLines', 0);
    else
        error('文件未找到: %s', file_path);
    end
end
%% 加载所有数据集
% 训练数据
train_FD001 = get_data('train_FD001.txt');
train_FD002 = get_data('train_FD002.txt');
train_FD003 = get_data('train_FD003.txt');
train_FD004 = get_data('train_FD004.txt');

% RUL数据
RUL_FD001 = get_data('RUL_FD001.txt');
RUL_FD002 = get_data('RUL_FD002.txt');
RUL_FD003 = get_data('RUL_FD003.txt');
RUL_FD004 = get_data('RUL_FD004.txt');

% 测试数据
test_FD001 = get_data('test_FD001.txt');
test_FD002 = get_data('test_FD002.txt');
test_FD003 = get_data('test_FD003.txt');
test_FD004 = get_data('test_FD004.txt');

%% 设置列名
col_names = {'ID', 'cycle', 'op_set_1', 'op_set_2', 'op_set_3', ...
    'sensor_1', 'sensor_2', 'sensor_3', 'sensor_4', 'sensor_5', ...
    'sensor_6', 'sensor_7', 'sensor_8', 'sensor_9', 'sensor_10', ...
    'sensor_11', 'sensor_12', 'sensor_13', 'sensor_14', 'sensor_15', ...
    'sensor_16', 'sensor_17', 'sensor_18', 'sensor_19', 'sensor_20', ...
    'sensor_21'};
col_name_RUL = {'RUL'};

% 为所有数据集分配列名
datasets = {train_FD001, train_FD002, train_FD003, train_FD004, ...
    test_FD001, test_FD002, test_FD003, test_FD004, ...
    RUL_FD001, RUL_FD002, RUL_FD003, RUL_FD004};

col_sets = {repmat({col_names}, 1, 8), repmat({col_name_RUL}, 1, 4)};

fori = 1:12
    ifi <= 8
        datasets{i}.Properties.VariableNames = col_names;
    else
        datasets{i}.Properties.VariableNames = col_name_RUL;
    end
end
% 将更新后的数据集赋值回原始变量
train_FD001 = datasets{1};
train_FD002 = datasets{2};
train_FD003 = datasets{3};
train_FD004 = datasets{4};

test_FD001 = datasets{5};
test_FD002 = datasets{6};
test_FD003 = datasets{7};
test_FD004 = datasets{8};

RUL_FD001 = datasets{9};
RUL_FD002 = datasets{10};
RUL_FD003 = datasets{11};
RUL_FD004 = datasets{12};

数据质量检查

% 检查空值
fprintf('空值检查:\n');
fori = 1:8
    null_count = sum(any(ismissing(datasets{i}), 1));
    fprintf('数据集 %d: %d 个空值\n', i, null_count);
end

% 检查重复值
fprintf('\n重复值检查:\n');
fori = 1:8
    [~, idx] = unique(datasets{i}, 'rows');
    dup_count = size(datasets{i}, 1) - length(idx);
    fprintf('数据集 %d: %d 个重复值\n', i, dup_count);
end

MATLAB输出如下:

操作设置分布图

%% 创建统一绘图样式
myColors = [0 0.4470 0.7410; 0.8500 0.3250 0.0980; 0.9290 0.6940 0.1250; ...
    0.4940 0.1840 0.5560; 0.4660 0.6740 0.1880; 0.3010 0.7450 0.9330; ...
    0.6350 0.0780 0.1840];
set(groot, 'defaultFigureColor', 'white', ...
    'defaultAxesFontSize', 12, ...
    'defaultAxesLabelFontSizeMultiplier', 1.1, ...
    'defaultAxesTitleFontSizeMultiplier', 1.2, ...
    'defaultLineLineWidth', 1.5);

%% 操作设置分析 (FD001)
% 提取操作设置列
op_set_cols = contains(col_names, 'op_set');
op_set_names = col_names(op_set_cols);

% 直方图分布
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    data = train_FD001.(op_set_names{i});
    histogram(data, 'Normalization', 'probability', ...
        'FaceColor', myColors(i, :));
    title(sprintf('%s 分布', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i},'Interpreter', 'none');
    ylabel('相对频率');
    grid on;
    box off;
    if i==3
        xlim([80, 120]); % 手动设置 x 轴范围
    end
end
sgtitle('操作设置分布 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

操作设置随周期变化图

% 操作设置随周期变化
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    scatter(train_FD001.(op_set_names{i}), train_FD001.cycle, 8, ...
        train_FD001.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 随周期变化', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i}, 'Interpreter', 'none');
    ylabel('周期');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('操作设置随周期变化 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

传感器分析 (FD001)

以FD001为例:

% 提取传感器列
sensor_cols = contains(col_names, 'sensor');
sensor_names = col_names(sensor_cols);

% 传感器直方图
figure('Position', [100, 100, 1400, 800]);
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    data = train_FD001.(sensor_names{i});
    histogram(data, 'Normalization', 'probability', ...
        'FaceColor', myColors(mod(i,7)+1, :));
    title(sprintf('%s 分布', sensor_names{i}), 'FontSize', 10, 'Interpreter', 'none');
    grid on;
    box off;
end
sgtitle('传感器分布 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

传感器随周期变化

% 传感器随周期变化
figure('Position', [100, 100, 1800, 800]);
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    scatter(train_FD001.(sensor_names{i}), train_FD001.cycle, 8, ...
        train_FD001.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 随周期变化', sensor_names{i}), 'FontSize', 10, 'Interpreter', 'none');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('传感器读数随周期变化 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

操作设置与RUL(剩余寿命)的关系

%% 计算RUL (FD001)
% 计算每个引擎的最大周期
[G, ID_groups] = findgroups(train_FD001.ID);
max_cycle = splitapply(@max, train_FD001.cycle, G);
max_cycle_per_engine = table(ID_groups, max_cycle, 'VariableNames', {'ID', 'max_cycle'});

% 合并数据并计算RUL
train_FD001_merged = join(train_FD001, max_cycle_per_engine);
train_FD001_merged.RUL = train_FD001_merged.max_cycle - train_FD001_merged.cycle;

%% RUL分析 (FD001)
% 操作设置与RUL的关系
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    scatter(train_FD001_merged.(op_set_names{i}), train_FD001_merged.RUL, 8, ...
        train_FD001_merged.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 与RUL关系', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i}, 'Interpreter', 'none');
    ylabel('RUL');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('操作设置与RUL关系 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

传感器与RUL的关系

% 传感器与RUL的关系
figure('Position', [100, 100, 1800, 800]);
colormap(jet);                    % 使用更清晰的配色(如 parula, jet, hsv)
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    scatter(train_FD001_merged.(sensor_names{i}), train_FD001_merged.RUL, 8, ...
        train_FD001_merged.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sensor_names{i}, 'FontSize', 10, 'Interpreter', 'none');
    grid on;
end
sgtitle('传感器读数与RUL关系 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

随机选择5个引擎进行趋势分析

  • 操作设置随RUL变化趋势

engine_ids = randperm(100, 5); % 随机选择5个引擎

% 操作设置趋势分析
figure('Position', [100, 100, 1400, 600]);
tiledlayout(3, 5, 'TileSpacing', 'compact');
for i = 1:3
    for j = 1:5
        nexttile;
        engine_data = train_FD001_merged(train_FD001_merged.ID == engine_ids(j), :);
        plot(engine_data.RUL, engine_data.(op_set_names{i}), ...
            'Color', myColors(i, :), 'LineWidth', 1.8);
        title(sprintf('引擎 %d: %s', engine_ids(j), op_set_names{i}), 'Interpreter', 'none');
        xlabel('RUL', 'Interpreter', 'none');
        grid on;
    end
end
sgtitle('操作设置随RUL变化趋势 (随机引擎)', 'FontSize', 16, 'FontWeight', 'bold');
  • 传感器随RUL变化趋势

sensor_subset = sensor_names(1:6);
figure('Position', [100, 100, 1400, 800]);
tiledlayout(6, 5, 'TileSpacing', 'compact');
for i = 1:6
    for j = 1:5
        nexttile;
        engine_data = train_FD001_merged(train_FD001_merged.ID == engine_ids(j), :);
        plot(engine_data.RUL, engine_data.(sensor_subset{i}), ...
            'Color', myColors(mod(i,7)+1, :), 'LineWidth', 1.8);
        title(sprintf('引擎 %d: %s', engine_ids(j), sensor_subset{i}), 'Interpreter', 'none');
        xlabel('RUL');
        grid on;
    end
end
sgtitle('传感器读数随RUL变化趋势 (随机引擎)', 'FontSize', 16, 'FontWeight', 'bold');

三、完整版代码直接复制

%% 初始化环境
clear; clc; close all;
addpath(genpath(pwd)); % 添加当前目录到路径

% 定义读取数据的函数
function data = get_data(file_name)
    file_path = fullfile('C-MAPSS-Data\', file_name);
    if exist(file_path, 'file') == 2
        data = readtable(file_path, 'Delimiter', ' ', 'MultipleDelimsAsOne', true, ...
            'ReadVariableNames', false,'HeaderLines', 0);
    else
        error('文件未找到: %s', file_path);
    end
end
%% 加载所有数据集
% 训练数据
train_FD001 = get_data('train_FD001.txt');
train_FD002 = get_data('train_FD002.txt');
train_FD003 = get_data('train_FD003.txt');
train_FD004 = get_data('train_FD004.txt');

% RUL数据
RUL_FD001 = get_data('RUL_FD001.txt');
RUL_FD002 = get_data('RUL_FD002.txt');
RUL_FD003 = get_data('RUL_FD003.txt');
RUL_FD004 = get_data('RUL_FD004.txt');

% 测试数据
test_FD001 = get_data('test_FD001.txt');
test_FD002 = get_data('test_FD002.txt');
test_FD003 = get_data('test_FD003.txt');
test_FD004 = get_data('test_FD004.txt');

%% 设置列名
col_names = {'ID', 'cycle', 'op_set_1', 'op_set_2', 'op_set_3', ...
    'sensor_1', 'sensor_2', 'sensor_3', 'sensor_4', 'sensor_5', ...
    'sensor_6', 'sensor_7', 'sensor_8', 'sensor_9', 'sensor_10', ...
    'sensor_11', 'sensor_12', 'sensor_13', 'sensor_14', 'sensor_15', ...
    'sensor_16', 'sensor_17', 'sensor_18', 'sensor_19', 'sensor_20', ...
    'sensor_21'};
col_name_RUL = {'RUL'};

% 为所有数据集分配列名
datasets = {train_FD001, train_FD002, train_FD003, train_FD004, ...
    test_FD001, test_FD002, test_FD003, test_FD004, ...
    RUL_FD001, RUL_FD002, RUL_FD003, RUL_FD004};

col_sets = {repmat({col_names}, 1, 8), repmat({col_name_RUL}, 1, 4)};

for i = 1:12
    if i <= 8
        datasets{i}.Properties.VariableNames = col_names;
    else
        datasets{i}.Properties.VariableNames = col_name_RUL;
    end
end
% 将更新后的数据集赋值回原始变量
train_FD001 = datasets{1};
train_FD002 = datasets{2};
train_FD003 = datasets{3};
train_FD004 = datasets{4};

test_FD001 = datasets{5};
test_FD002 = datasets{6};
test_FD003 = datasets{7};
test_FD004 = datasets{8};

RUL_FD001 = datasets{9};
RUL_FD002 = datasets{10};
RUL_FD003 = datasets{11};
RUL_FD004 = datasets{12};


%% 数据质量检查
% 检查空值
fprintf('空值检查:\n');
for i = 1:8
    null_count = sum(any(ismissing(datasets{i}), 1));
    fprintf('数据集 %d: %d 个空值\n', i, null_count);
end

% 检查重复值
fprintf('\n重复值检查:\n');
for i = 1:8
    [~, idx] = unique(datasets{i}, 'rows');
    dup_count = size(datasets{i}, 1) - length(idx);
    fprintf('数据集 %d: %d 个重复值\n', i, dup_count);
end

%% 创建统一绘图样式
myColors = [0 0.4470 0.7410; 0.8500 0.3250 0.0980; 0.9290 0.6940 0.1250; ...
    0.4940 0.1840 0.5560; 0.4660 0.6740 0.1880; 0.3010 0.7450 0.9330; ...
    0.6350 0.0780 0.1840];
set(groot, 'defaultFigureColor', 'white', ...
    'defaultAxesFontSize', 12, ...
    'defaultAxesLabelFontSizeMultiplier', 1.1, ...
    'defaultAxesTitleFontSizeMultiplier', 1.2, ...
    'defaultLineLineWidth', 1.5);

%% 操作设置分析 (FD001)
% 提取操作设置列
op_set_cols = contains(col_names, 'op_set');
op_set_names = col_names(op_set_cols);

% 直方图分布
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    data = train_FD001.(op_set_names{i});
    histogram(data, 'Normalization', 'probability', ...
        'FaceColor', myColors(i, :));
    title(sprintf('%s 分布', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i},'Interpreter', 'none');
    ylabel('相对频率');
    grid on;
    box off;
    if i==3
        xlim([80, 120]); % 手动设置 x 轴范围
    end
end
sgtitle('操作设置分布 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

% 操作设置随周期变化
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    scatter(train_FD001.(op_set_names{i}), train_FD001.cycle, 8, ...
        train_FD001.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 随周期变化', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i}, 'Interpreter', 'none');
    ylabel('周期');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('操作设置随周期变化 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

%% 传感器分析 (FD001)
% 提取传感器列
sensor_cols = contains(col_names, 'sensor');
sensor_names = col_names(sensor_cols);

% 传感器直方图
figure('Position', [100, 100, 1400, 800]);
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    data = train_FD001.(sensor_names{i});
    histogram(data, 'Normalization', 'probability', ...
        'FaceColor', myColors(mod(i,7)+1, :));
    title(sprintf('%s 分布', sensor_names{i}), 'FontSize', 10, 'Interpreter', 'none');
    grid on;
    box off;
end
sgtitle('传感器分布 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

% 传感器随周期变化
figure('Position', [100, 100, 1800, 800]);
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    scatter(train_FD001.(sensor_names{i}), train_FD001.cycle, 8, ...
        train_FD001.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 随周期变化', sensor_names{i}), 'FontSize', 10, 'Interpreter', 'none');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('传感器读数随周期变化 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

%% 计算RUL (FD001)
% 计算每个引擎的最大周期
[G, ID_groups] = findgroups(train_FD001.ID);
max_cycle = splitapply(@max, train_FD001.cycle, G);
max_cycle_per_engine = table(ID_groups, max_cycle, 'VariableNames', {'ID', 'max_cycle'});

% 合并数据并计算RUL
train_FD001_merged = join(train_FD001, max_cycle_per_engine);
train_FD001_merged.RUL = train_FD001_merged.max_cycle - train_FD001_merged.cycle;

%% RUL分析 (FD001)
% 操作设置与RUL的关系
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    scatter(train_FD001_merged.(op_set_names{i}), train_FD001_merged.RUL, 8, ...
        train_FD001_merged.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 与RUL关系', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i}, 'Interpreter', 'none');
    ylabel('RUL');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('操作设置与RUL关系 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

% 传感器与RUL的关系
figure('Position', [100, 100, 1800, 800]);
colormap(jet);                    % 使用更清晰的配色(如 parula, jet, hsv)
tiledlayout(3, 7, 'TileSpacing', 'compact');
for i = 1:21
    nexttile;
    scatter(train_FD001_merged.(sensor_names{i}), train_FD001_merged.RUL, 8, ...
        train_FD001_merged.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sensor_names{i}, 'FontSize', 10, 'Interpreter', 'none');
    grid on;
end
sgtitle('传感器读数与RUL关系 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');

%% 相关性分析 (FD001)
% 提取相关列
corr_cols = contains(train_FD001_merged.Properties.VariableNames, ...
    {'op_set', 'sensor', 'RUL'}) | ...
    strcmp(train_FD001_merged.Properties.VariableNames, 'cycle');
corr_data = train_FD001_merged(:, corr_cols);

% 计算并显示相关系数矩阵
corr_matrix = corr(table2array(corr_data), 'Rows', 'complete');
figure('Position', [100, 100, 1000, 900]);
imagesc(corr_matrix);
colorbar;
% colormap(jet);
title('特征相关性矩阵 (FD001)', 'FontSize', 16, 'FontWeight', 'bold');
axis square;

%% 随机选择5个引擎进行趋势分析
engine_ids = randperm(100, 5); % 随机选择5个引擎

% 操作设置趋势分析
figure('Position', [100, 100, 1400, 600]);
tiledlayout(3, 5, 'TileSpacing', 'compact');
for i = 1:3
    for j = 1:5
        nexttile;
        engine_data = train_FD001_merged(train_FD001_merged.ID == engine_ids(j), :);
        plot(engine_data.RUL, engine_data.(op_set_names{i}), ...
            'Color', myColors(i, :), 'LineWidth', 1.8);
        title(sprintf('引擎 %d: %s', engine_ids(j), op_set_names{i}), 'Interpreter', 'none');
        xlabel('RUL', 'Interpreter', 'none');
        grid on;
    end
end
sgtitle('操作设置随RUL变化趋势 (随机引擎)', 'FontSize', 16, 'FontWeight', 'bold');

% 传感器趋势分析 (选择前6个传感器示例)
sensor_subset = sensor_names(1:6);
figure('Position', [100, 100, 1400, 800]);
tiledlayout(6, 5, 'TileSpacing', 'compact');
for i = 1:6
    for j = 1:5
        nexttile;
        engine_data = train_FD001_merged(train_FD001_merged.ID == engine_ids(j), :);
        plot(engine_data.RUL, engine_data.(sensor_subset{i}), ...
            'Color', myColors(mod(i,7)+1, :), 'LineWidth', 1.8);
        title(sprintf('引擎 %d: %s', engine_ids(j), sensor_subset{i}), 'Interpreter', 'none');
        xlabel('RUL');
        grid on;
    end
end
sgtitle('传感器读数随RUL变化趋势 (随机引擎)', 'FontSize', 16, 'FontWeight', 'bold');

%% 处理FD002数据集 (示例)
[G, ID_groups] = findgroups(train_FD002.ID);
max_cycle = splitapply(@max, train_FD002.cycle, G);
max_cycle_per_engine = table(ID_groups, max_cycle, 'VariableNames', {'ID', 'max_cycle'});

train_FD002_merged = join(train_FD002, max_cycle_per_engine);
train_FD002_merged.RUL = train_FD002_merged.max_cycle - train_FD002_merged.cycle;

% 操作设置与RUL关系
figure('Position', [100, 100, 1200, 500]);
for i = 1:3
    subplot(1, 3, i);
    scatter(train_FD002_merged.(op_set_names{i}), train_FD002_merged.RUL, 8, ...
        train_FD002_merged.ID, 'filled', 'MarkerEdgeAlpha', 0.3, 'MarkerFaceAlpha', 0.3);
    title(sprintf('%s 与RUL关系 (FD002)', op_set_names{i}), 'FontWeight', 'bold', 'Interpreter', 'none');
    xlabel(op_set_names{i}, 'Interpreter', 'none');
    ylabel('RUL');
    colormap(turbo);
    colorbar('off');
    grid on;
end
sgtitle('操作设置与RUL关系 (FD002)', 'FontSize', 16, 'FontWeight', 'bold');

四、代码运行简单说明

从NASA官方直接下载数据:https://data.nasa.gov/dataset/cmapss-jet-engine-simulated-data  

复制以上代码即可直接一键出图。

获取更多优秀代码

或者复制链接跳转:https://docs.qq.com/sheet/DU3NjYkF5TWdFUnpu

端午安康

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值