MATLAB学习文档(二十二)

目录

10.5表格相关练习题

[30 个地区一年的存取款数据分析](#30 个地区一年的存取款数据分析)

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[步骤2: 创建表格并添加变量名](#步骤2: 创建表格并添加变量名)

[步骤3: 计算每个地区的年总存款和总取款](#步骤3: 计算每个地区的年总存款和总取款)

[步骤4: 计算净存款额(存款-取款)](#步骤4: 计算净存款额(存款-取款))

[步骤5: 数据分析](#步骤5: 数据分析)

[5.1 找出存款最多的地区](#5.1 找出存款最多的地区)

[5.2 找出取款最多的地区](#5.2 找出取款最多的地区)

[5.3 找出净存款额最高的地区](#5.3 找出净存款额最高的地区)

[步骤6: 数据可视化](#步骤6: 数据可视化)

[步骤7: 月度趋势分析](#步骤7: 月度趋势分析)

过程

12个地区的高考招生数据整理

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[步骤2: 创建嵌套表格结构](#步骤2: 创建嵌套表格结构)

[步骤3: 数据整理和分析](#步骤3: 数据整理和分析)

[3.1 计算每个地区的总招生计划、总报名人数和总录取人数](#3.1 计算每个地区的总招生计划、总报名人数和总录取人数)

[3.2 计算每所高校在各地区的平均数据](#3.2 计算每所高校在各地区的平均数据)

[步骤4: 数据可视化](#步骤4: 数据可视化)

[4.1 各地区总报名人数和总录取人数对比](#4.1 各地区总报名人数和总录取人数对比)

[4.2 各地区平均录取率](#4.2 各地区平均录取率)

[4.3 各高校平均最低分数](#4.3 各高校平均最低分数)

[步骤5: 导出数据到Excel](#步骤5: 导出数据到Excel)

过程

将24个月的招聘数据汇总到同一表格

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[步骤2: 生成24个月的模拟数据](#步骤2: 生成24个月的模拟数据)

[步骤3: 将24个月的数据汇总到同一表格](#步骤3: 将24个月的数据汇总到同一表格)

[步骤4: 数据分析](#步骤4: 数据分析)

[4.1 按月份统计招聘数量](#4.1 按月份统计招聘数量)

[4.2 按职位名称统计招聘数量](#4.2 按职位名称统计招聘数量)

[4.3 按工作地点统计招聘数量](#4.3 按工作地点统计招聘数量)

[4.4 按学历要求统计招聘数量](#4.4 按学历要求统计招聘数量)

[步骤5: 数据可视化](#步骤5: 数据可视化)

[5.1 月度招聘趋势](#5.1 月度招聘趋势)

[5.2 各职位招聘数量](#5.2 各职位招聘数量)

[5.3 各城市招聘数量](#5.3 各城市招聘数量)

[5.4 学历要求分布](#5.4 学历要求分布)

[步骤6: 薪资分析](#步骤6: 薪资分析)

[步骤7: 导出汇总数据](#步骤7: 导出汇总数据)

过程

共享单车数据预处理

[步骤1: 创建模拟的共享单车数据](#步骤1: 创建模拟的共享单车数据)

[步骤2: 数据预处理](#步骤2: 数据预处理)

[2.1 检查缺失值](#2.1 检查缺失值)

[2.2 处理异常值](#2.2 处理异常值)

[2.3 处理重复值](#2.3 处理重复值)

[2.4 数据转换](#2.4 数据转换)

[2.5 添加骑行速度列(公里/小时)](#2.5 添加骑行速度列(公里/小时))

[步骤3: 数据质量评估](#步骤3: 数据质量评估)

[3.1 统计数据预处理后的基本情况](#3.1 统计数据预处理后的基本情况)

[3.2 检查骑行速度是否合理](#3.2 检查骑行速度是否合理)

[步骤4: 数据分析和可视化](#步骤4: 数据分析和可视化)

[4.1 骑行时长分布](#4.1 骑行时长分布)

[4.2 骑行距离分布](#4.2 骑行距离分布)

[4.3 每小时使用量](#4.3 每小时使用量)

[4.4 工作日vs周末使用量](#4.4 工作日vs周末使用量)

[步骤5: 热点分析](#步骤5: 热点分析)

[5.1 统计每个站点的出发和到达次数](#5.1 统计每个站点的出发和到达次数)

[5.2 可视化热门站点](#5.2 可视化热门站点)

[5.3 分析站点间的流量](#5.3 分析站点间的流量)

[步骤6: 导出预处理后的数据](#步骤6: 导出预处理后的数据)

过程

57个分拣中心的小时货量数据整理

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[步骤2: 创建表格并添加变量名](#步骤2: 创建表格并添加变量名)

[步骤3: 数据整理](#步骤3: 数据整理)

[3.1 计算每个分拣中心的日总货量](#3.1 计算每个分拣中心的日总货量)

[3.2 计算每个分拣中心的平均小时货量](#3.2 计算每个分拣中心的平均小时货量)

[3.3 找出每个分拣中心的峰值小时和峰值货量](#3.3 找出每个分拣中心的峰值小时和峰值货量)

[3.4 计算每个分拣中心的货量变异系数(标准差/均值)](#3.4 计算每个分拣中心的货量变异系数(标准差/均值))

[步骤4: 按小时汇总所有分拣中心的货量](#步骤4: 按小时汇总所有分拣中心的货量)

[步骤5: 数据分析和可视化](#步骤5: 数据分析和可视化)

[5.1 找出货量最大的分拣中心](#5.1 找出货量最大的分拣中心)

[5.2 找出峰值货量最大的分拣中心](#5.2 找出峰值货量最大的分拣中心)

[5.3 找出货量最稳定的分拣中心(变异系数最小)](#5.3 找出货量最稳定的分拣中心(变异系数最小))

[5.4 找出货量波动最大的分拣中心(变异系数最大)](#5.4 找出货量波动最大的分拣中心(变异系数最大))

[步骤6: 数据可视化](#步骤6: 数据可视化)

[6.1 所有分拣中心的日内货量变化](#6.1 所有分拣中心的日内货量变化)

[6.2 日总货量TOP10的分拣中心](#6.2 日总货量TOP10的分拣中心)

[6.3 小时总货量变化趋势](#6.3 小时总货量变化趋势)

[6.4 分拣中心聚类分析(基于日内货量模式)](#6.4 分拣中心聚类分析(基于日内货量模式))

[步骤7: 导出数据](#步骤7: 导出数据)

过程

蔬菜商品表格的联接

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[1.1 创建蔬菜基本信息表](#1.1 创建蔬菜基本信息表)

[1.2 创建蔬菜](#1.2 创建蔬菜)价格表

[1.3 创建蔬菜销量表](#1.3 创建蔬菜销量表)

[步骤2: 表格联接](#步骤2: 表格联接)

[2.1 将基本信息表与价格表联接](#2.1 将基本信息表与价格表联接)

[2.2 将上述结果与销量表联接](#2.2 将上述结果与销量表联接)

[步骤3: 数据处理和分析](#步骤3: 数据处理和分析)

[3.1 计算销售额](#3.1 计算销售额)

[3.2 按类别汇总](#3.2 按类别汇总)

[3.3 按产地汇总](#3.3 按产地汇总)

[3.4 按蔬菜汇总](#3.4 按蔬菜汇总)

[3.5 按日期汇总](#3.5 按日期汇总)

[步骤6: 导出数据](#步骤6: 导出数据)

过程

同步空气质量时间表

[步骤1: 创建模拟数据](#步骤1: 创建模拟数据)

[1.1 创建监测站信息](#1.1 创建监测站信息)

[1.2 创建空气质量监测数据](#1.2 创建空气质量监测数据)

[步骤2: 同步时间表](#步骤2: 同步时间表)

[2.1 创建完整的时间戳序列(所有监测站的时间戳并集)](#2.1 创建完整的时间戳序列(所有监测站的时间戳并集))

[2.2 为每个监测站创建同步后的数据](#2.2 为每个监测站创建同步后的数据)

[2.3 合并所有监测站的数据](#2.3 合并所有监测站的数据)

[步骤3: 缺失值处理](#步骤3: 缺失值处理)

[3.1 统计缺失值情况](#3.1 统计缺失值情况)

[3.2 使用线性插值处理缺失值](#3.2 使用线性插值处理缺失值)

[3.3 再次统计缺失值情况](#3.3 再次统计缺失值情况)

[步骤4: 计算空气质量指数(AQI)](#步骤4: 计算空气质量指数(AQI))

[4.1 定义各指标的浓度限值和对应的IAQI计算函数](#4.1 定义各指标的浓度限值和对应的IAQI计算函数)

[4.2 定义计算IAQI的函数](#4.2 定义计算IAQI的函数)

[4.3 计算各指标的IAQI](#4.3 计算各指标的IAQI)

[4.4 计算AQI(取各指标IAQI的最大值)](#4.4 计算AQI(取各指标IAQI的最大值))

[4.5 确定首要污染物](#4.5 确定首要污染物)

[4.6 确定空气质量等级](#4.6 确定空气质量等级)

[步骤5: 数据分析和可视化](#步骤5: 数据分析和可视化)

[5.1 按监测站统计AQI平均值](#5.1 按监测站统计AQI平均值)

[5.2 按空气质量等级统计记录数](#5.2 按空气质量等级统计记录数)

[5.3 按首要污染物统计记录数](#5.3 按首要污染物统计记录数)

[5.4 按小时统计平均AQI](#5.4 按小时统计平均AQI)

[5.5 可视化](#5.5 可视化)

[步骤6: 导出数据](#步骤6: 导出数据)

过程

[步骤4: 数据可视化](#步骤4: 数据可视化)

[4.1 各类别蔬菜的总销售额](#4.1 各类别蔬菜的总销售额)

[4.2 不同产地蔬菜的平均价格](#4.2 不同产地蔬菜的平均价格)

[4.3 销量TOP10的蔬菜](#4.3 销量TOP10的蔬菜)

[4.4 每日总销售额变化趋势](#4.4 每日总销售额变化趋势)

[4.5 价格与销量的散点图](#4.5 价格与销量的散点图)

[步骤5: 高级分析](#步骤5: 高级分析)

[5.1 计算价格弹性](#5.1 计算价格弹性)

[5.2 可视化价格弹性](#5.2 可视化价格弹性)


10.5表格相关练习题

30 个地区一年的存取款数据分析

步骤1: 创建模拟数据
Matlab 复制代码
% 假设我们有30个地区,12个月的存取款数据

regions = string(arrayfun(@(x) sprintf('地区%d', x), 1:30, 'UniformOutput', false));

months = string(arrayfun(@(x) sprintf('%d月', x), 1:12, 'UniformOutput', false));

% 生成随机存取款数据(单位:万元)

deposit_data = randi([1000, 5000], 30, 12); % 存款数据

withdrawal_data = randi([500, 3000], 30, 12); % 取款数据
步骤2: 创建表格并添加变量名
Matlab 复制代码
deposit_table = array2table(deposit_data, 'VariableNames', months);

deposit_table.Properties.DimensionNames{1} = '地区';

deposit_table.地区 = regions;

withdrawal_table = array2table(withdrawal_data, 'VariableNames', months);

withdrawal_table.Properties.DimensionNames{1} = '地区';

withdrawal_table.地区 = regions;
步骤3: 计算每个地区的年总存款和总取款
Matlab 复制代码
deposit_table.年总存款 = sum(deposit_table{:, 2:13}, 2);

withdrawal_table.年总取款 = sum(withdrawal_table{:, 2:13}, 2);
步骤4: 计算净存款额(存款-取款)
Matlab 复制代码
net_deposit = table();

net_deposit.地区 = regions;

net_deposit.年总存款 = deposit_table.年总存款;

net_deposit.年总取款 = withdrawal_table.年总取款;

net_deposit.净存款额 = net_deposit.年总存款 - net_deposit.年总取款;
步骤5: 数据分析
5.1 找出存款最多的地区
Matlab 复制代码
[max_deposit, max_idx] = max(net_deposit.年总存款);

fprintf('存款最多的地区是%s,存款总额为%.2f万元\n', net_deposit.地区{max_idx}, max_deposit);
5.2 找出取款最多的地区
Matlab 复制代码
[max_withdrawal, max_w_idx] = max(net_deposit.年总取款);

fprintf('取款最多的地区是%s,取款总额为%.2f万元\n', net_deposit.地区{max_w_idx}, max_withdrawal);
5.3 找出净存款额最高的地区
Matlab 复制代码
[max_net, max_net_idx] = max(net_deposit.净存款额);

fprintf('净存款额最高的地区是%s,净存款额为%.2f万元\n', net_deposit.地区{max_net_idx}, max_net);
步骤6: 数据可视化
Matlab 复制代码
figure;

subplot(2,1,1);

bar(net_deposit.年总存款);

title('各地区年总存款');

xlabel('地区');

ylabel('存款额(万元)');

xticks(1:30);

xticklabels(net_deposit.地区);

xtickangle(45);

subplot(2,1,2);

bar(net_deposit.年总取款);

title('各地区年总取款');

xlabel('地区');

ylabel('取款额(万元)');

xticks(1:30);

xticklabels(net_deposit.地区);

xtickangle(45);
步骤7: 月度趋势分析
Matlab 复制代码
monthly_deposit = sum(deposit_table{:, 2:13}, 1);

monthly_withdrawal = sum(withdrawal_table{:, 2:13}, 1);

figure;

plot(1:12, monthly_deposit, '-o', 'LineWidth', 2);

hold on;

plot(1:12, monthly_withdrawal, '-s', 'LineWidth', 2);

title('月度存取款趋势');

xlabel('月份');

ylabel('金额(万元)');

legend('总存款', '总取款');

grid on;

xticks(1:12);

xticklabels(months);

xtickangle(45);
过程
  1. 首先创建了30个地区和12个月的标签,然后生成了随机的存取款数据
  2. 将数据转换为表格格式,便于后续处理和分析
  3. 计算了每个地区的年总存款和总取款,并计算净存款额
  4. 进行了基本的数据分析,找出存款最多、取款最多和净存款额最高的地区
  5. 通过条形图可视化各地区的存取款情况
  6. 通过折线图展示了月度存取款趋势,便于观察季节性变化

12个地区的高考招生数据整理

步骤1: 创建模拟数据
Matlab 复制代码
% 假设有12个地区,每个地区有5所高校的招生数据

regions = string(arrayfun(@(x) sprintf('地区%d', x), 1:12, 'UniformOutput', false));

universities = string(arrayfun(@(x) sprintf('高校%d', x), 1:5, 'UniformOutput', false));

% 生成随机招生数据

% 招生计划数、报名人数、实际录取人数、最低录取分数

plan_data = randi([100, 500], 12, 5); % 招生计划数

apply_data = randi([200, 1000], 12, 5); % 报名人数

admit_data = randi([100, 500], 12, 5); % 实际录取人数

score_data = randi([400, 700], 12, 5); % 最低录取分数
步骤2: 创建嵌套表格结构
Matlab 复制代码
% 创建一个主表格,每个地区一行

admission_table = table();

admission_table.地区 = regions;

% 为每个地区创建一个包含高校数据的子表格

for i = 1:12

    % 创建子表格

    sub_table = table();

    sub_table.高校 = universities';

    sub_table.招生计划 = plan_data(i,:)';

    sub_table.报名人数 = apply_data(i,:)';

    sub_table.实际录取 = admit_data(i,:)';

    sub_table.最低分数 = score_data(i,:)';

    % 计算录取率和报录比

    sub_table.录取率 = sub_table.实际录取 ./ sub_table.报名人数 * 100;

    sub_table.报录比 = sub_table.报名人数 ./ sub_table.招生计划;

    % 将子表格添加到主表格

    admission_table.高校数据{i} = sub_table;

end
步骤3: 数据整理和分析
3.1 计算每个地区的总招生计划、总报名人数和总录取人数
Matlab 复制代码
region_summary = table();

region_summary.地区 = regions;

region_summary.总招生计划 = sum(plan_data, 2);

region_summary.总报名人数 = sum(apply_data, 2);

region_summary.总录取人数 = sum(admit_data, 2);

region_summary.平均录取率 = region_summary.总录取人数 ./ region_summary.总报名人数 * 100;

region_summary.平均报录比 = region_summary.总报名人数 ./ region_summary.总招生计划;
3.2 计算每所高校在各地区的平均数据
Matlab 复制代码
university_summary = table();

university_summary.高校 = universities';

university_summary.平均招生计划 = mean(plan_data, 1)';

university_summary.平均报名人数 = mean(apply_data, 1)';

university_summary.平均录取人数 = mean(admit_data, 1)';

university_summary.平均最低分数 = mean(score_data, 1)';

university_summary.平均录取率 = mean(admit_data ./ apply_data * 100, 1)';

university_summary.平均报录比 = mean(apply_data ./ plan_data, 1)';
步骤4: 数据可视化
4.1 各地区总报名人数和总录取人数对比
Matlab 复制代码
figure;

bar([region_summary.总报名人数, region_summary.总录取人数]);

title('各地区总报名人数与总录取人数对比');

xlabel('地区');

ylabel('人数');

legend('报名人数', '录取人数');

xticks(1:12);

xticklabels(region_summary.地区);

xtickangle(45);
4.2 各地区平均录取率
Matlab 复制代码
figure;

bar(region_summary.平均录取率);

title('各地区平均录取率');

xlabel('地区');

ylabel('录取率(%)');

xticks(1:12);

xticklabels(region_summary.地区);

xtickangle(45);
4.3 各高校平均最低分数
Matlab 复制代码
figure;

bar(university_summary.平均最低分数);

title('各高校平均最低录取分数');

xlabel('高校');

ylabel('分数');

xticks(1:5);

xticklabels(university_summary.高校);

xtickangle(45);
步骤5: 导出数据到Excel
Matlab 复制代码
% writetable(admission_table, '高考招生数据.xlsx');

% writetable(region_summary, '地区招生汇总.xlsx');

% writetable(university_summary, '高校招生汇总.xlsx');
过程
  1. 创建了12个地区和5所高校的模拟招生数据,包括招生计划、报名人数、实际录取人数和最低录取分数
  2. 使用嵌套表格结构组织数据,主表格包含地区信息,每个地区对应一个包含高校数据的子表格
  3. 计算了录取率和报录比等关键指标
  4. 生成了两个汇总表格:一个按地区汇总,一个按高校汇总
  5. 通过条形图可视化各地区报名与录取人数对比、各地区平均录取率以及各高校平均最低分数

将24个月的招聘数据汇总到同一表格

步骤1: 创建模拟数据
Matlab 复制代码
% 假设我们有24个月的招聘数据,每个月份是一个单独的表格

% 每个表格包含: 职位名称、公司名称、薪资范围、工作地点、学历要求、工作经验要求

% 创建24个月份标签

months = string(arrayfun(@(x) sprintf('%d年%d月', 2021+floor((x-1)/12), mod(x-1,12)+1), 1:24, 'UniformOutput', false));

% 定义可能的职位类别

job_titles = ["软件工程师", "数据分析师", "产品经理", "市场营销", "人力资源", "财务会计", "销售代表", "客户服务"];

companies = ["公司A", "公司B", "公司C", "公司D", "公司E", "公司F", "公司G", "公司H"];

locations = ["北京", "上海", "广州", "深圳", "杭州", "成都", "武汉", "西安"];

education = ["本科", "硕士", "博士", "大专", "不限"];

experience = ["应届生", "1-3年", "3-5年", "5-10年", "10年以上"];
步骤2: 生成24个月的模拟数据
Matlab 复制代码
monthly_data = cell(24, 1); % 使用cell数组存储每个月的表格

for m = 1:24

    % 每个月随机生成50-100条招聘记录

    num_records = randi([50, 100]);

    % 随机生成数据

    jobs = job_titles(randi(length(job_titles), num_records, 1));

    comps = companies(randi(length(companies), num_records, 1));

    locs = locations(randi(length(locations), num_records, 1));

    edu = education(randi(length(education), num_records, 1));

    exp = experience(randi(length(experience), num_records, 1));

    % 生成薪资范围(单位:千元/月)

    min_salary = randi([5, 20], num_records, 1);

    max_salary = min_salary + randi([5, 15], num_records, 1);

    salary = arrayfun(@(x,y) sprintf('%d-%d', x, y), min_salary, max_salary, 'UniformOutput', false);

    % 创建表格

    monthly_table = table();

    monthly_table.职位名称 = jobs;

    monthly_table.公司名称 = comps;

    monthly_table.薪资范围 = salary;

    monthly_table.工作地点 = locs;

    monthly_table.学历要求 = edu;

    monthly_table.工作经验 = exp;

    % 存储到cell数组

    monthly_data{m} = monthly_table;

end
步骤3: 将24个月的数据汇总到同一表格
Matlab 复制代码
% 添加月份列并合并所有表格

for m = 1:24

    monthly_data{m}.月份 = repmat(months(m), height(monthly_data{m}), 1);

end

% 使用vertcat垂直合并所有表格

combined_data = vertcat(monthly_data{:});
步骤4: 数据分析
4.1 按月份统计招聘数量
Matlab 复制代码
monthly_count = groupcounts(combined_data, '月份');
4.2 按职位名称统计招聘数量
Matlab 复制代码
job_count = groupcounts(combined_data, '职位名称');
4.3 按工作地点统计招聘数量
Matlab 复制代码
location_count = groupcounts(combined_data, '工作地点');
4.4 按学历要求统计招聘数量
Matlab 复制代码
education_count = groupcounts(combined_data, '学历要求');
步骤5: 数据可视化
5.1 月度招聘趋势
Matlab 复制代码
figure;

plot(1:24, monthly_count.Percent, '-o', 'LineWidth', 2);

title('24个月招聘数量趋势');

xlabel('月份');

ylabel('招聘数量');

grid on;

xticks(1:24);

xticklabels(months);

xtickangle(45);
5.2 各职位招聘数量
Matlab 复制代码
figure;

pie(job_count.Percent, job_count.职位名称);

title('各职位招聘数量占比');
5.3 各城市招聘数量
Matlab 复制代码
figure;

barh(location_count.Percent);

title('各城市招聘数量');

xlabel('招聘数量');

ylabel('城市');

yticks(1:length(location_count.工作地点));

yticklabels(location_count.工作地点);
5.4 学历要求分布
Matlab 复制代码
figure;

pie(education_count.Percent, education_count.学历要求);

title('学历要求分布');
步骤6: 薪资分析
Matlab 复制代码
% 从薪资范围中提取最低薪资和最高薪资

min_sal = zeros(height(combined_data), 1);

max_sal = zeros(height(combined_data), 1);

for i = 1:height(combined_data)

    salary_str = combined_data.薪资范围{i};

    parts = strsplit(salary_str, '-');

    min_sal(i) = str2double(parts{1});

    max_sal(i) = str2double(parts{2});

end

% 添加到表格

combined_data.最低薪资 = min_sal;

combined_data.最高薪资 = max_sal;

combined_data.平均薪资 = (min_sal + max_sal) / 2;

% 按职位分析薪资

job_salary = groupsummary(combined_data, '职位名称', {'mean', 'min', 'max'}, '平均薪资');

% 可视化各职位平均薪资

figure;

bar(job_salary.平均薪资);

title('各职位平均薪资');

xlabel('职位');

ylabel('平均薪资(千元/月)');

xticks(1:length(job_salary.职位名称));

xticklabels(job_salary.职位名称);

xtickangle(45);
步骤7: 导出汇总数据
Matlab 复制代码
% writetable(combined_data, '24个月招聘数据汇总.xlsx');
过程
  1. 创建了24个月的模拟招聘数据,包括职位名称、公司名称、薪资范围、工作地点、学历要求和工作经验
  2. 使用cell数组存储每个月的表格,然后通过添加月份列并使用vertcat函数将所有数据合并到一个表格中
  3. 进行了多维度分析:按月份、职位名称、工作地点和学历要求统计招聘数量
  4. 通过多种图表可视化数据:折线图展示月度趋势,饼图展示职位和学历分布,水平条形图展示城市分布
  5. 对薪资数据进行了特殊处理,从字符串中提取数值并计算平均薪资
  6. 按职位分析了薪资情况,并通过条形图展示各职位的平均薪资

共享单车数据预处理

步骤1: 创建模拟的共享单车数据
Matlab 复制代码
% 假设数据包含: 单车ID、开始时间、结束时间、开始位置、结束位置、骑行时长、骑行距离

% 创建可能的单车ID

bike_ids = string(arrayfun(@(x) sprintf('B%04d', x), 1:100, 'UniformOutput', false));

% 创建位置点(假设有20个固定站点)

locations = string(arrayfun(@(x) sprintf('站点%d', x), 1:20, 'UniformOutput', false));

% 生成1000条随机骑行记录

num_records = 1000;

bike_data = table();

% 随机分配单车ID

bike_data.单车ID = bike_ids(randi(length(bike_ids), num_records, 1));

% 生成开始和结束时间(假设数据来自2023年1月)

start_dates = datetime(2023, 1, 1) + hours(randi(0, 23, num_records, 1)) + minutes(randi(0, 59, num_records, 1));

ride_durations = minutes(randi(5, 120, num_records, 1)); % 骑行时长5-120分钟

end_dates = start_dates + ride_durations;

bike_data.开始时间 = start_dates;

bike_data.结束时间 = end_dates;

% 随机分配开始和结束位置

bike_data.开始位置 = locations(randi(length(locations), num_records, 1));

bike_data.结束位置 = locations(randi(length(locations), num_records, 1));

% 计算骑行时长(分钟)

bike_data.骑行时长 = minutes(bike_data.结束时间 - bike_data.开始时间);

% 生成骑行距离(公里)

bike_data.骑行距离 = 0.2 + rand(num_records, 1) * 4.8; % 0.2-5公里
步骤2: 数据预处理
2.1 检查缺失值
Matlab 复制代码
missing_values = ismissing(bike_data);

fprintf('缺失值统计:\n');

for i = 1:width(bike_data)

    fprintf('%s: %d\n', bike_data.Properties.VariableNames{i}, sum(missing_values(:, i)));

end
2.2 处理异常值
Matlab 复制代码
% 检查骑行时长是否异常(假设超过3小时为异常)

abnormal_duration = bike_data.骑行时长 > 180;

fprintf('\n骑行时长异常记录数: %d\n', sum(abnormal_duration));

% 检查骑行距离是否异常(假设超过10公里为异常)

abnormal_distance = bike_data.骑行距离 > 10;

fprintf('骑行距离异常记录数: %d\n', sum(abnormal_distance));

% 标记异常记录

bike_data.异常记录 = abnormal_duration | abnormal_distance;
2.3 处理重复值
Matlab 复制代码
% 检查是否有完全相同的记录

[~, unique_idx] = unique(bike_data(:, 1:6), 'rows');

duplicates = setdiff(1:height(bike_data), unique_idx);

fprintf('\n重复记录数: %d\n', length(duplicates));

% 删除重复记录

bike_data = bike_data(unique_idx, :);
2.4 数据转换
Matlab 复制代码
% 添加日期、星期几和小时列,便于后续分析

bike_data.日期 = date(bike_data.开始时间);

bike_data.星期几 = weekday(bike_data.开始时间);

bike_data.小时 = hour(bike_data.开始时间);

% 将星期几转换为文本

weekdays = ["日", "一", "二", "三", "四", "五", "六"];

bike_data.星期几文本 = string(arrayfun(@(x) weekdays(x), bike_data.星期几, 'UniformOutput', false));

% 添加是否周末列

bike_data.是否周末 = bike_data.星期几 == 1 | bike_data.星期几 == 7;
2.5 添加骑行速度列(公里/小时)
Matlab 复制代码
bike_data.骑行速度 = bike_data.骑行距离 ./ (bike_data.骑行时长 / 60);
步骤3: 数据质量评估
3.1 统计数据预处理后的基本情况
Matlab 复制代码
fprintf('\n数据预处理后基本情况:\n');

fprintf('总记录数: %d\n', height(bike_data));

fprintf('异常记录数: %d\n', sum(bike_data.异常记录));

fprintf('正常记录数: %d\n', sum(~bike_data.异常记录));
3.2 检查骑行速度是否合理
Matlab 复制代码
abnormal_speed = bike_data.骑行速度 > 25 | bike_data.骑行速度 < 3; % 假设速度超过25km/h或低于3km/h为异常

fprintf('骑行速度异常记录数: %d\n', sum(abnormal_speed));

% 更新异常记录标记

bike_data.异常记录 = bike_data.异常记录 | abnormal_speed;
步骤4: 数据分析和可视化
4.1 骑行时长分布
Matlab 复制代码
figure;

subplot(2,2,1);

histogram(bike_data.骑行时长(~bike_data.异常记录), 20);

title('骑行时长分布(正常数据)');

xlabel('时长(分钟)');

ylabel('频次');
4.2 骑行距离分布
Matlab 复制代码
subplot(2,2,2);

histogram(bike_data.骑行距离(~bike_data.异常记录), 20);

title('骑行距离分布(正常数据)');

xlabel('距离(公里)');

ylabel('频次');
4.3 每小时使用量
Matlab 复制代码
hourly_usage = groupcounts(bike_data(~bike_data.异常记录, :), '小时');

subplot(2,2,3);

bar(hourly_usage.小时, hourly_usage.Percent);

title('每小时使用量');

xlabel('小时');

ylabel('使用次数');

xticks(0:23);
4.4 工作日vs周末使用量
Matlab 复制代码
weekday_weekend = groupcounts(bike_data(~bike_data.异常记录, :), '是否周末');

subplot(2,2,4);

pie(weekday_weekend.Percent, ["工作日", "周末"]);

title('工作日vs周末使用量');
步骤5: 热点分析
5.1 统计每个站点的出发和到达次数
Matlab 复制代码
start_counts = groupcounts(bike_data(~bike_data.异常记录, :), '开始位置');

end_counts = groupcounts(bike_data(~bike_data.异常记录, :), '结束位置');

% 合并统计结果

location_stats = outerjoin(start_counts, end_counts, 'Keys', '开始位置', 'MergeKeys', true);

location_stats.Properties.VariableNames{1} = '站点';

location_stats.Properties.VariableNames{2} = '出发次数';

location_stats.Properties.VariableNames{3} = '到达次数';

% 填充缺失值

location_stats.出发次数(ismissing(location_stats.出发次数)) = 0;

location_stats.到达次数(ismissing(location_stats.到达次数)) = 0;

% 计算总使用次数

location_stats.总使用次数 = location_stats.出发次数 + location_stats.到达次数;

% 按总使用次数排序

location_stats = sortrows(location_stats, '总使用次数', 'descend');

5.2 可视化热门站点
figure;

subplot(2,1,1);

barh(location_stats.总使用次数(1:10));

title('热门站点TOP10');

xlabel('使用次数');

ylabel('站点');

yticks(1:10);

yticklabels(location_stats.站点(1:10));
5.3 分析站点间的流量
Matlab 复制代码
% 创建站点间的流量矩阵

flow_matrix = zeros(length(locations), length(locations));

for i = 1:height(bike_data(~bike_data.异常_record, :))

    if ~bike_data.异常记录(i)

        start_loc = bike_data.开始位置{i};

        end_loc = bike_data.结束位置{i};

        start_idx = find(strcmp(locations, start_loc));

        end_idx = find(strcmp(locations, end_loc));

        if ~isempty(start_idx) && ~isempty(end_idx)

            flow_matrix(start_idx, end_idx) = flow_matrix(start_idx, end_idx) + 1;

        end

    end

end

% 找出流量最大的前10条路线

[flow_values, flow_indices] = sort(flow_matrix(:), 'descend');

top_flows = flow_values(1:10);

% 获取对应的站点对

[top_i, top_j] = ind2sub(size(flow_matrix), flow_indices(1:10));

top_routes = arrayfun(@(x,y) sprintf('%s -> %s', locations{x}, locations{y}), top_i, top_j, 'UniformOutput', false);

% 可视化热门路线

subplot(2,1,2);

barh(top_flows);

title('热门路线TOP10');

xlabel('流量');

ylabel('路线');

yticks(1:10);

yticklabels(top_routes);
步骤6: 导出预处理后的数据
Matlab 复制代码
% writetable(bike_data, '共享单车预处理数据.xlsx');

% writetable(location_stats, '站点使用统计.xlsx');
过程
  1. 创建了模拟的共享单车数据,包括单车ID、开始时间、结束时间、开始位置、结束位置、骑行时长和骑行距离
  2. 进行了全面的数据预处理:
  3. 检查并统计缺失值
  4. 识别并标记异常值(如过长的骑行时间或过长的骑行距离)
  5. 删除重复记录
  6. 进行数据转换,添加日期、星期几、小时和是否周末等列
  7. 计算骑行速度并检查是否合理
  8. 评估了数据质量,统计了异常记录和正常记录的数量
  9. 通过多种图表进行数据分析和可视化:
  10. 骑行时长和距离的分布直方图
  11. 每小时使用量的条形图
  12. 工作日vs周末使用量的饼图
  13. 进行了热点分析:
  14. 统计每个站点的出发和到达次数,找出热门站点
  15. 分析站点间的流量,找出热门路线

57个分拣中心的小时货量数据整理

步骤1: 创建模拟数据
Matlab 复制代码
% 假设有57个分拣中心,记录24小时的货量数据

% 创建分拣中心ID

centers = string(arrayfun(@(x) sprintf('C%03d', x), 1:57, 'UniformOutput', false));

% 创建小时标签(0-23时)

hours = 0:23;

% 生成57个分拣中心24小时的货量数据

% 考虑到分拣中心的货量通常有日内变化模式,我们使用正弦函数加随机噪声生成数据

base_volume = 1000; % 基础货量

amplitude = 500; % 波动幅度

peak_hour = 14; % 峰值小时(下午2点)

% 创建货量数据矩阵

volume_data = zeros(57, 24);

for i = 1:57

    % 每个分拣中心的基础货量和波动幅度略有不同

    center_base = base_volume + randi([-200, 200]);

    center_amplitude = amplitude + randi([-100, 100]);

    center_peak = peak_hour + randi([-2, 2]); % 峰值时间略有不同

    % 生成日内变化模式

    for h = 1:24

        % 使用正弦函数模拟日内变化,并添加随机噪声

        hour_factor = sin(pi * (h-1-center_peak+12)/12);

        volume_data(i, h) = max(0, center_base + center_amplitude * hour_factor + randn * 50);

    end

end
步骤2: 创建表格并添加变量名
Matlab 复制代码
volume_table = array2table(volume_data, 'VariableNames', string(hours));

volume_table.Properties.DimensionNames{1} = '分拣中心';

volume_table.分拣中心 = centers;
步骤3: 数据整理
3.1 计算每个分拣中心的日总货量
Matlab 复制代码
volume_table.日总货量 = sum(volume_table{:, 2:25}, 2);
3.2 计算每个分拣中心的平均小时货量
Matlab 复制代码
volume_table.平均小时货量 = mean(volume_table{:, 2:25}, 2);
3.3 找出每个分拣中心的峰值小时和峰值货量
Matlab 复制代码
[peak_volumes, peak_hours] = max(volume_data, [], 2);

volume_table.峰值小时 = peak_hours - 1; % 转换为0-23小时

volume_table.峰值货量 = peak_volumes;
3.4 计算每个分拣中心的货量变异系数(标准差/均值)
Matlab 复制代码
hourly_volumes = volume_table{:, 2:25};

volume_table.变异系数 = std(hourly_volumes, 0, 2) ./ mean(hourly_volumes, 2);
步骤4: 按小时汇总所有分拣中心的货量
Matlab 复制代码
hourly_summary = table();

hourly_summary.小时 = hours';

hourly_summary.总货量 = sum(volume_data, 1)';

hourly_summary.平均货量 = mean(volume_data, 1)';

hourly_summary.最大货量 = max(volume_data, [], 1)';

hourly_summary.最小货量 = min(volume_data, [], 1)';
步骤5: 数据分析和可视化
5.1 找出货量最大的分拣中心
Matlab 复制代码
[max_daily, max_center_idx] = max(volume_table.日总货量);

fprintf('日总货量最大的分拣中心是%s,货量为%.2f\n', volume_table.分拣中心{max_center_idx}, max_daily);
5.2 找出峰值货量最大的分拣中心
Matlab 复制代码
[max_peak, max_peak_idx] = max(volume_table.峰值货量);

fprintf('峰值货量最大的分拣中心是%s,峰值货量为%.2f\n', volume_table.分拣中心{max_peak_idx}, max_peak);
5.3 找出货量最稳定的分拣中心(变异系数最小)
Matlab 复制代码
[min_cv, min_cv_idx] = min(volume_table.变异系数);

fprintf('货量最稳定的分拣中心是%s,变异系数为%.4f\n', volume_table.分拣中心{min_cv_idx}, min_cv);
5.4 找出货量波动最大的分拣中心(变异系数最大)
Matlab 复制代码
[max_cv, max_cv_idx] = max(volume_table.变异系数);

fprintf('货量波动最大的分拣中心是%s,变异系数为%.4f\n', volume_table.分拣中心{max_cv_idx}, max_cv);
步骤6: 数据可视化
6.1 所有分拣中心的日内货量变化
Matlab 复制代码
figure;

plot(hours, volume_data', 'LineWidth', 1);

hold on;

plot(hours, hourly_summary.平均货量, 'k-', 'LineWidth', 3);

title('所有分拣中心的日内货量变化');

xlabel('小时');

ylabel('货量');

legend('平均货量', 'Location', 'best');

grid on;

xticks(hours);
6.2 日总货量TOP10的分拣中心
Matlab 复制代码
sorted_centers = sortrows(volume_table, '日总货量', 'descend');

top10_centers = sorted_centers(1:10, :);

figure;

bar(top10_centers.日总货量);

title('日总货量TOP10的分拣中心');

xlabel('分拣中心');

ylabel('日总货量');

xticks(1:10);

xticklabels(top10_centers.分拣中心);

xtickangle(45);
6.3 小时总货量变化趋势
Matlab 复制代码
figure;

plot(hours, hourly_summary.总货量, '-o', 'LineWidth', 2);

hold on;

plot(hours, hourly_summary.平均货量, '-s', 'LineWidth', 2);

plot(hours, hourly_summary.最大货量, '-^', 'LineWidth', 1);

plot(hours, hourly_summary.最小货量, '-v', 'LineWidth', 1);

title('小时货量变化趋势');

xlabel('小时');

ylabel('货量');

legend('总货量', '平均货量', '最大货量', '最小货量', 'Location', 'best');

grid on;

xticks(hours);
6.4 分拣中心聚类分析(基于日内货量模式)
Matlab 复制代码
% 使用K-means聚类将分拣中心分为5类

num_clusters = 5;

[idx, centroids] = kmeans(volume_data, num_clusters);

% 将聚类结果添加到表格

volume_table.聚类类别 = idx;

% 可视化聚类结果

figure;

for c = 1:num_clusters

    subplot(num_clusters, 1, c);

    cluster_centers = volume_data(idx == c, :);

    plot(hours, cluster_centers', 'LineWidth', 1);

    hold on;

    plot(hours, centroids(c, :), 'k-', 'LineWidth', 3);

    title(sprintf('类别%d (%d个分拣中心)', c, sum(idx == c)));

    xlabel('小时');

    ylabel('货量');

    grid on;

    xticks(hours);

end
步骤7: 导出数据
Matlab 复制代码
% writetable(volume_table, '分拣中心货量数据.xlsx');

% writetable(hourly_summary, '小时货量汇总.xlsx');
过程
  1. 创建了57个分拣中心24小时的模拟货量数据,使用正弦函数模拟日内变化模式,并添加随机噪声
  2. 将数据转换为表格格式,便于后续处理和分析
  3. 进行了数据整理,计算了每个分拣中心的日总货量、平均小时货量、峰值小时和峰值货量
  4. 计算了货量变异系数,用于衡量货量波动程度
  5. 按小时汇总了所有分拣中心的货量数据
  6. 进行了数据分析,找出了货量最大、峰值最大、最稳定和波动最大的分拣中心
  7. 通过多种图表进行数据可视化:
  8. 所有分拣中心的日内货量变化曲线
  9. 日总货量TOP10的分拣中心条形图
  10. 小时货量变化趋势图
  11. 使用K-means聚类分析将分拣中心按日内货量模式分为5类,并可视化各类别的货量模式

蔬菜商品表格的联接

步骤1: 创建模拟数据

假设我们有三个表格:蔬菜基本信息表、蔬菜价格表和蔬菜销量表

1.1 创建蔬菜基本信息表
Matlab 复制代码
vegetable_names = ["白菜", "菠菜", "芹菜", "生菜", "油菜", ...

                  "西红柿", "黄瓜", "茄子", "辣椒", "豆角", ...

                  "土豆", "萝卜", "胡萝卜", "洋葱", "大蒜", ...

                  "南瓜", "冬瓜", "丝瓜", "苦瓜", "西葫芦"];

categories = ["叶菜类", "叶菜类", "叶菜类", "叶菜类", "叶菜类", ...

             "茄果类", "瓜菜类", "茄果类", "茄果类", "豆类", ...

             "根茎类", "根茎类", "根茎类", "根茎类", "根茎类", ...

             "瓜菜类", "瓜菜类", "瓜菜类", "瓜菜类", "瓜菜类"];

origins = ["本地", "外地", "本地", "本地", "本地", ...

          "本地", "本地", "外地", "本地", "本地", ...

          "本地", "本地", "外地", "外地", "本地", ...

          "本地", "本地", "本地", "本地", "本地"];

% 创建基本信息表

basic_info = table();

basic_info.蔬菜ID = string(arrayfun(@(x) sprintf('V%03d', x), 1:20, 'UniformOutput', false));

basic_info.蔬菜名称 = vegetable_names';

basic_info.类别 = categories';

basic_info.产地 = origins';
1.2 创建蔬菜价格表
Matlab 复制代码
% 假设有30天的价格数据

dates = datetime(2023, 6, 1) + caldays(0:29);

% 生成随机价格数据(单位:元/公斤)

price_data = table();

price_rows = [];

for d = 1:30

    for v = 1:20

        price_rows = [price_rows; {dates(d), basic_info.蔬菜ID{v}, basic_info.蔬菜名称{v}, ...

                                 2 + rand() * 8}]; % 价格在2-10元/公斤之间

    end

end

price_data = cell2table(price_rows, 'VariableNames', {'日期', '蔬菜ID', '蔬菜名称', '价格'});
1.3 创建蔬菜销量表
Matlab 复制代码
% 生成随机销量数据(单位:公斤)

sales_data = table();

sales_rows = [];

for d = 1:30

    for v = 1:20

        % 销量与价格有一定负相关关系

        base_sales = 500;

        price_factor = 1000 ./ price_data{(d-1)*20+v, '价格'}; % 价格越高,销量越低

        random_factor = 0.8 + rand() * 0.4; % 随机波动因子

        sales = base_sales * price_factor * random_factor;

        sales_rows = [sales_rows; {dates(d), basic_info.蔬菜ID{v}, basic_info.蔬菜名称{v}, sales}];

    end

end

sales_data = cell2table(sales_rows, 'VariableNames', {'日期', '蔬菜ID', '蔬菜名称', '销量'});
步骤2: 表格联接
2.1 将基本信息表与价格表联接
Matlab 复制代码
basic_price = outerjoin(basic_info, price_data, 'Keys', '蔬菜ID', 'MergeKeys', true);

basic_price.Properties.VariableNames{1} = '蔬菜ID';

basic_price.Properties.VariableNames{2} = '蔬菜名称_basic';

basic_price.Properties.VariableNames{3} = '类别';

basic_price.Properties.VariableNames{4} = '产地';

basic_price.Properties.VariableNames{5} = '日期';

basic_price.Properties.VariableNames{6} = '蔬菜名称_price';

basic_price.Properties.VariableNames{7} = '价格';

% 删除重复的蔬菜名称列

basic_price.蔬菜名称_price = [];
2.2 将上述结果与销量表联接
Matlab 复制代码
full_data = outerjoin(basic_price, sales_data, 'Keys', {'蔬菜ID', '日期'}, 'MergeKeys', true);

full_data.Properties.VariableNames{1} = '蔬菜ID';

full_data.Properties.VariableNames{2} = '蔬菜名称';

full_data.Properties.VariableNames{3} = '类别';

full_data.Properties.VariableNames{4} = '产地';

full_data.Properties.VariableNames{5} = '日期';

full_data.Properties.VariableNames{6} = '价格';

full_data.Properties.VariableNames{7} = '蔬菜名称_sales';

full_data.Properties.VariableNames{8} = '销量';

% 删除重复的蔬菜名称列

full_data.蔬菜名称_sales = [];
步骤3: 数据处理和分析
3.1 计算销售额
Matlab 复制代码
full_data.销售额 = full_data.价格 .* full_data.销量;
3.2 按类别汇总
Matlab 复制代码
category_summary = groupsummary(full_data, '类别', {'mean', 'sum'}, {'价格', '销量', '销售额'});

category_summary.Properties.VariableNames{1} = '类别';

category_summary.Properties.VariableNames{2} = '组数';

category_summary.Properties.VariableNames{3} = '平均价格';

category_summary.Properties.VariableNames{4} = '总销量';

category_summary.Properties.VariableNames{5} = '总销售额';
3.3 按产地汇总
Matlab 复制代码
origin_summary = groupsummary(full_data, '产地', {'mean', 'sum'}, {'价格', '销量', '销售额'});

origin_summary.Properties.VariableNames{1} = '产地';

origin_summary.Properties.VariableNames{2} = '组数';

origin_summary.Properties.VariableNames{3} = '平均价格';

origin_summary.Properties.VariableNames{4} = '总销量';

origin_summary.Properties.VariableNames{5} = '总销售额';
3.4 按蔬菜汇总
Matlab 复制代码
vegetable_summary = groupsummary(full_data, '蔬菜名称', {'mean', 'sum'}, {'价格', '销量', '销售额'});

vegetable_summary.Properties.VariableNames{1} = '蔬菜名称';

vegetable_summary.Properties.VariableNames{2} = '组数';

vegetable_summary.Properties.VariableNames{3} = '平均价格';

vegetable_summary.Properties.VariableNames{4} = '总销量';

vegetable_summary.Properties.VariableNames{5} = '总销售额';
3.5 按日期汇总
Matlab 复制代码
date_summary = groupsummary(full_data, '日期', {'mean', 'sum'}, {'价格', '销量', '销售额'});

date_summary.Properties.VariableNames{1} = '日期';

date_summary.Properties.VariableNames{2} = '组数';

date_summary.Properties.VariableNames{3} = '平均价格';

date_summary.Properties.VariableNames{4} = '总销量';

date_summary.Properties.VariableNames{5} = '总销售额';
步骤4: 数据可视化
4.1 各类别蔬菜的总销售额
Matlab 复制代码
figure;

pie(category_summary.总销售额, category_summary.类别);

title('各类别蔬菜的总销售额');
4.2 不同产地蔬菜的平均价格
Matlab 复制代码
figure;

bar(origin_summary.平均价格);

title('不同产地蔬菜的平均价格');

xlabel('产地');

ylabel('平均价格(元/公斤)');

xticks(1:2);

xticklabels(origin_summary.产地);
4.3 销量TOP10的蔬菜
Matlab 复制代码
sorted_vegetables = sortrows(vegetable_summary, '总销量', 'descend');

top10_vegetables = sorted_vegetables(1:10, :);

figure;

barh(top10_vegetables.总销量);

title('销量TOP10的蔬菜');

xlabel('总销量(公斤)');

ylabel('蔬菜');

yticks(1:10);

yticklabels(top10_vegetables.蔬菜名称);
4.4 每日总销售额变化趋势
Matlab 复制代码
figure;

plot(date_summary.日期, date_summary.总销售额, '-o', 'LineWidth', 2);

title('每日总销售额变化趋势');

xlabel('日期');

ylabel('总销售额(元)');

grid on;

xtickangle(45);
4.5 价格与销量的散点图
Matlab 复制代码
figure;

scatter(full_data.价格, full_data.销量, 'filled');

title('价格与销量的关系');

xlabel('价格(元/公斤)');

ylabel('销量(公斤)');

grid on;

% 计算相关系数

price_sales_corr = corr(full_data.价格, full_data.销量);

fprintf('价格与销量的相关系数: %.4f\n', price_sales_corr);
步骤5: 高级分析
5.1 计算价格弹性
Matlab 复制代码
% 价格弹性 = 销量变化百分比 / 价格变化百分比

% 我们按蔬菜计算价格弹性

price_elasticity = table();

price_elasticity.蔬菜名称 = vegetable_names';

for v = 1:20

    % 获取单个蔬菜的数据

    veg_data = full_data(strcmp(full_data.蔬菜名称, vegetable_names{v}), :);

    % 按价格排序

    veg_data = sortrows(veg_data, '价格');

    % 计算价格和销量的对数

    log_price = log(veg_data.价格);

    log_sales = log(veg_data.销量);

    % 使用线性回归计算弹性

    X = [ones(size(log_price)), log_price];

    b = X \ log_sales;

    elasticity = b(2); % 弹性系数

    price_elasticity.价格弹性(v) = elasticity;

end
5.2 可视化价格弹性
Matlab 复制代码
sorted_elasticity = sortrows(price_elasticity, '价格弹性');

figure;

barh(sorted_elasticity.价格弹性);

title('各蔬菜的价格弹性');

xlabel('价格弹性');

ylabel('蔬菜');

yticks(1:20);

yticklabels(sorted_elasticity.蔬菜名称);

grid on;

% 添加参考线

xline(0, 'r-', 'LineWidth', 2);

text(-1.5, 10, '缺乏弹性', 'Color', 'r');

text(0.5, 10, '富有弹性', 'Color', 'r');
步骤6: 导出数据
Matlab 复制代码
% writetable(full_data, '蔬菜商品完整数据.xlsx');

% writetable(category_summary, '类别汇总.xlsx');

% writetable(origin_summary, '产地汇总.xlsx');

% writetable(vegetable_summary, '蔬菜汇总.xlsx');

% writetable(date_summary, '日期汇总.xlsx');

% writetable(price_elasticity, '价格弹性.xlsx');
过程
  1. 创建了三个模拟表格:蔬菜基本信息表、蔬菜价格表和蔬菜销量表
  2. 基本信息表包含蔬菜ID、名称、类别和产地
  3. 价格表包含30天的价格数据
  4. 销量表包含30天的销量数据,销量与价格有一定负相关关系
  5. 使用outerjoin函数将三个表格联接成一个完整的数据表
  6. 进行了数据处理和分析:
  7. 计算销售额
  8. 按类别、产地、蔬菜和日期进行汇总统计
  9. 通过多种图表进行数据可视化:
  10. 各类别蔬菜的总销售额饼图
  11. 不同产地蔬菜的平均价格条形图
  12. 销量TOP10的蔬菜水平条形图
  13. 每日总销售额变化趋势折线图
  14. 价格与销量的散点图,并计算相关系数
  15. 进行了高级分析,计算了价格弹性(销量变化百分比/价格变化百分比)
  16. 使用对数线性回归方法计算每种蔬菜的价格弹性
  17. 通过水平条形图展示各蔬菜的价格弹性,并标注缺乏弹性和富有弹性的区域

同步空气质量时间表

步骤1: 创建模拟数据

假设我们有多个空气质量监测站的数据,需要同步时间表

1.1 创建监测站信息
Matlab 复制代码
stations = ["监测站A", "监测站B", "监测站C", "监测站D", "监测站E"];

locations = ["城区", "工业区", "郊区", "居民区", "商业区"];

station_info = table();

station_info.监测站ID = string(arrayfun(@(x) sprintf('S%03d', x), 1:5, 'UniformOutput', false));

station_info.监测站名称 = stations';

station_info.位置类型 = locations';
1.2 创建空气质量监测数据
Matlab 复制代码
% 假设监测周期为30天,每小时记录一次

start_date = datetime(2019, 1, 1);

end_date = datetime(2019, 1, 30);

timestamps = start_date:hours(1):end_date;

% 空气质量指标: PM2.5, PM10, SO2, NO2, O3, CO

% 创建5个监测站的数据

station_data = cell(5, 1); % 使用cell数组存储每个监测站的数据

for s = 1:5

    % 每个监测站的数据量可能不同(模拟不同监测站可能有缺失记录)

    % 假设监测站A和C数据完整,其他监测站有部分缺失

    if s == 1 || s == 3

        % 数据完整

        station_timestamps = timestamps;

    else

        % 随机缺失5-15%的数据

        missing_percent = 0.05 + rand() * 0.1;

        num_missing = round(length(timestamps) * missing_percent);

        missing_indices = randperm(length(timestamps), num_missing);

        station_timestamps = timestamps;

        station_timestamps(missing_indices) = [];

    end

    % 生成空气质量数据

    num_records = length(station_timestamps);

    % PM2.5 (μg/m³)

    if s == 2  % 工业区PM2.5较高

        pm25 = 50 + randn(num_records, 1) * 30;

    elseif s == 3  % 郊区PM2.5较低

        pm25 = 20 + randn(num_records, 1) * 10;

    else

        pm25 = 35 + randn(num_records, 1) * 20;

    end

    pm25 = max(0, pm25); % 确保非负

    % PM10 (μg/m³)

    pm10 = pm25 + 10 + randn(num_records, 1) * 15;

    pm10 = max(0, pm10);

    % SO2 (μg/m³)

    if s == 2  % 工业区SO2较高

        so2 = 20 + randn(num_records, 1) * 10;

    else

        so2 = 5 + randn(num_records, 1) * 5;

    end

    so2 = max(0, so2);

    % NO2 (μg/m³)

    if s == 2  % 工业区NO2较高

        no2 = 40 + randn(num_records, 1) * 20;

    elseif s == 4  % 居民区NO2中等

        no2 = 30 + randn(num_records, 1) * 15;

    else

        no2 = 20 + randn(num_records, 1) * 10;

    end

    no2 = max(0, no2);

    % O3 (μg/m³) - 日间较高,夜间较低

    hour_of_day = hour(station_timestamps);

    o3_base = 50 + 40 * sin(pi * (hour_of_day - 6) / 12); % 峰值在下午

    o3 = o3_base + randn(num_records, 1) * 15;

    o3 = max(0, o3);

    % CO (mg/m³)

    if s == 2  % 工业区CO较高

        co = 1.2 + randn(num_records, 1) * 0.5;

    else

        co = 0.8 + randn(num_records, 1) * 0.3;

    end

    co = max(0, co);

    % 创建表格

    station_table = table();

    station_table.时间戳 = station_timestamps;

    station_table.监测站ID = repmat(station_info.监测站ID(s), num_records, 1);

    station_table.PM25 = pm25;

    station_table.PM10 = pm10;

    station_table.SO2 = so2;

    station_table.NO2 = no2;

    station_table.O3 = o3;

    station_table.CO = co;

    % 存储到cell数组

    station_data{s} = station_table;

end
步骤2: 同步时间表
2.1 创建完整的时间戳序列(所有监测站的时间戳并集)
Matlab 复制代码
all_timestamps = unique(vertcat(station_data{:}.时间戳));

all_timestamps = sort(all_timestamps);
2.2 为每个监测站创建同步后的数据
Matlab 复制代码
synced_data = cell(5, 1);

for s = 1:5

    % 获取原始数据

    original_data = station_data{s};

    % 创建新的表格,包含所有时间戳

    new_table = table();

    new_table.时间戳 = all_timestamps;

    new_table.监测站ID = repmat(station_info.监测站ID(s), length(all_timestamps), 1);

    % 初始化空气质量指标列为NaN

    new_table.PM25 = NaN(length(all_timestamps), 1);

    new_table.PM10 = NaN(length(all_timestamps), 1);

    new_table.SO2 = NaN(length(all_timestamps), 1);

    new_table.NO2 = NaN(length(all_timestamps), 1);

    new_table.O3 = NaN(length(all_timestamps), 1);

    new_table.CO = NaN(length(all_timestamps), 1);

    % 填充已有数据

    for i = 1:length(all_timestamps)

        % 查找当前时间戳在原始数据中的位置

        idx = find(original_data.时间戳 == all_timestamps(i));

        if ~isempty(idx)

            % 找到匹配项,复制数据

            new_table.PM25(i) = original_data.PM25(idx);

            new_table.PM10(i) = original_data.PM10(idx);

            new_table.SO2(i) = original_data.SO2(idx);

            new_table.NO2(i) = original_data.NO2(idx);

            new_table.O3(i) = original_data.O3(idx);

            new_table.CO(i) = original_data.CO(idx);

        end

    end

    % 存储同步后的数据

    synced_data{s} = new_table;

end
2.3 合并所有监测站的数据
Matlab 复制代码
combined_data = vertcat(synced_data{:});
步骤3: 缺失值处理
3.1 统计缺失值情况
Matlab 复制代码
missing_counts = sum(ismissing(combined_data(:, 3:8)));

fprintf('各指标缺失值统计:\n');

fprintf('PM25: %d\n', missing_counts(1));

fprintf('PM10: %d\n', missing_counts(2));

fprintf('SO2: %d\n', missing_counts(3));

fprintf('NO2: %d\n', missing_counts(4));

fprintf('O3: %d\n', missing_counts(5));

fprintf('CO: %d\n', missing_counts(6));
3.2 使用线性插值处理缺失值
Matlab 复制代码
% 按监测站分组处理缺失值

for s = 1:5

    station_id = station_info.监测站ID(s);

    station_mask = strcmp(combined_data.监测站ID, station_id);

    station_data_subset = combined_data(station_mask, :);

    % 对每个空气质量指标进行插值

    for col = 3:8

        % 获取列名

        col_name = combined_data.Properties.VariableNames{col};

        % 获取数据

        data = station_data_subset.(col_name);

        % 找出非NaN值的索引

        valid_idx = ~isnan(data);

        % 如果有至少两个非NaN值,进行插值

        if sum(valid_idx) >= 2

            % 使用线性插值

            data = interp1(find(valid_idx), data(valid_idx), 1:length(data), 'linear', 'extrap');

            % 更新数据

            combined_data{station_mask, col_name} = data;

        end

    end

end
3.3 再次统计缺失值情况
Matlab 复制代码
missing_counts_after = sum(ismissing(combined_data(:, 3:8)));

fprintf('\n插值后各指标缺失值统计:\n');

fprintf('PM25: %d\n', missing_counts_after(1));

fprintf('PM10: %d\n', missing_counts_after(2));

fprintf('SO2: %d\n', missing_counts_after(3));

fprintf('NO2: %d\n', missing_counts_after(4));

fprintf('O3: %d\n', missing_counts_after(5));

fprintf('CO: %d\n', missing_counts_after(6));
步骤4: 计算空气质量指数(AQI)
4.1 定义各指标的浓度限值和对应的IAQI计算函数
Matlab 复制代码
% PM2.5

pm25_breakpoints = [0, 35, 75, 115, 150, 250, 350, 500];

pm25_iaqi_breakpoints = [0, 50, 100, 150, 200, 300, 400, 500];

% PM10

pm10_breakpoints = [0, 50, 150, 250, 350, 420, 500, 600];

pm10_iaqi_breakpoints = [0, 50, 100, 150, 200, 300, 400, 500];

% SO2

so2_breakpoints = [0, 50, 150, 475, 800, 1600, 2100, 2620];

so2_iaqi_breakpoints = [0, 50, 100, 150, 200, 300, 400, 500];

% NO2

no2_breakpoints = [0, 40, 80, 180, 280, 565, 750, 940];

no2_iaqi_breakpoints = [0, 50, 100, 150, 200, 300, 400, 500];

% O3

o3_breakpoints = [0, 100, 160, 215, 265, 800];

o3_iaqi_breakpoints = [0, 50, 100, 150, 200, 300];

% CO (单位转换为mg/m³)

co_breakpoints = [0, 2, 4, 14, 24, 36, 48, 60];

co_iaqi_breakpoints = [0, 50, 100, 150, 200, 300, 400, 500];
4.2 定义计算IAQI的函数
Matlab 复制代码
calculate_iaqi = @(concentration, bp_lo, bp_hi, iaqi_lo, iaqi_hi) ...

    (iaqi_hi - iaqi_lo) / (bp_hi - bp_lo) * (concentration - bp_lo) + iaqi_lo;
4.3 计算各指标的IAQI
Matlab 复制代码
% 初始化IAQI列

combined_data.IAQI_PM25 = NaN(height(combined_data), 1);

combined_data.IAQI_PM10 = NaN(height(combined_data), 1);

combined_data.IAQI_SO2 = NaN(height(combined_data), 1);

combined_data.IAQI_NO2 = NaN(height(combined_data), 1);

combined_data.IAQI_O3 = NaN(height(combined_data), 1);

combined_data.IAQI_CO = NaN(height(combined_data), 1);

% 计算PM2.5的IAQI

for i = 1:height(combined_data)

    pm25 = combined_data.PM25(i);

    % 找到对应的浓度区间

    for j = 1:length(pm25_breakpoints)-1

        if pm25 >= pm25_breakpoints(j) && pm25 <= pm25_breakpoints(j+1)

            bp_lo = pm25_breakpoints(j);

            bp_hi = pm25_breakpoints(j+1);

            iaqi_lo = pm25_iaqi_breakpoints(j);

            iaqi_hi = pm25_iaqi_breakpoints(j+1);

            combined_data.IAQI_PM25(i) = calculate_iaqi(pm25, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end

% 计算PM10的IAQI

for i = 1:height(combined_data)

    pm10 = combined_data.PM10(i);

    % 找到对应的浓度区间

    for j = 1:length(pm10_breakpoints)-1

        if pm10 >= pm10_breakpoints(j) && pm10 <= pm10_breakpoints(j+1)

            bp_lo = pm10_breakpoints(j);

            bp_hi = pm10_breakpoints(j+1);

            iaqi_lo = pm10_iaqi_breakpoints(j);

            iaqi_hi = pm10_iaqi_breakpoints(j+1);

            combined_data.IAQI_PM10(i) = calculate_iaqi(pm10, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end

% 计算SO2的IAQI

for i = 1:height(combined_data)

    so2 = combined_data.SO2(i);

    % 找到对应的浓度区间

    for j = 1:length(so2_breakpoints)-1

        if so2 >= so2_breakpoints(j) && so2 <= so2_breakpoints(j+1)

            bp_lo = so2_breakpoints(j);

            bp_hi = so2_breakpoints(j+1);

            iaqi_lo = so2_iaqi_breakpoints(j);

            iaqi_hi = so2_iaqi_breakpoints(j+1);

            combined_data.IAQI_SO2(i) = calculate_iaqi(so2, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end

% 计算NO2的IAQI

for i = 1:height(combined_data)

    no2 = combined_data.NO2(i);

    % 找到对应的浓度区间

    for j = 1:length(no2_breakpoints)-1

        if no2 >= no2_breakpoints(j) && no2 <= no2_breakpoints(j+1)

            bp_lo = no2_breakpoints(j);

            bp_hi = no2_breakpoints(j+1);

            iaqi_lo = no2_iaqi_breakpoints(j);

            iaqi_hi = no2_iaqi_breakpoints(j+1);

            combined_data.IAQI_NO2(i) = calculate_iaqi(no2, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end

% 计算O3的IAQI

for i = 1:height(combined_data)

    o3 = combined_data.O3(i);

    % 找到对应的浓度区间

    for j = 1:length(o3_breakpoints)-1

        if o3 >= o3_breakpoints(j) && o3 <= o3_breakpoints(j+1)

            bp_lo = o3_breakpoints(j);

            bp_hi = o3_breakpoints(j+1);

            iaqi_lo = o3_iaqi_breakpoints(j);

            iaqi_hi = o3_iaqi_breakpoints(j+1);

            combined_data.IAQI_O3(i) = calculate_iaqi(o3, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end

% 计算CO的IAQI

for i = 1:height(combined_data)

    co = combined_data.CO(i);

    % 找到对应的浓度区间

    for j = 1:length(co_breakpoints)-1

        if co >= co_breakpoints(j) && co <= co_breakpoints(j+1)

            bp_lo = co_breakpoints(j);

            bp_hi = co_breakpoints(j+1);

            iaqi_lo = co_iaqi_breakpoints(j);

            iaqi_hi = co_iaqi_breakpoints(j+1);

            combined_data.IAQI_CO(i) = calculate_iaqi(co, bp_lo, bp_hi, iaqi_lo, iaqi_hi);

            break;

        end

    end

end
4.4 计算AQI(取各指标IAQI的最大值)
Matlab 复制代码
iaqi_columns = combined_data{:, {'IAQI_PM25', 'IAQI_PM10', 'IAQI_SO2', 'IAQI_NO2', 'IAQI_O3', 'IAQI_CO'}};

combined_data.AQI = max(iaqi_columns, [], 2);
4.5 确定首要污染物
Matlab 复制代码
% 找出每个记录的IAQI最大值对应的指标

combined_data.首要污染物 = strings(height(combined_data), 1);

pollutant_names = ["PM2.5", "PM10", "SO2", "NO2", "O3", "CO"];

for i = 1:height(combined_data)

    [~, max_idx] = max(iaqi_columns(i, :));

    combined_data.首要污染物(i) = pollutant_names(max_idx);

end
4.6 确定空气质量等级
Matlab 复制代码
combined_data.空气质量等级 = strings(height(combined_data), 1);

combined_data.等级描述 = strings(height(combined_data), 1);

for i = 1:height(combined_data)

    aqi = combined_data.AQI(i);

    if aqi <= 50

        combined_data.空气质量等级(i) = "一级";

        combined_data.等级描述(i) = "优";

    elseif aqi <= 100

        combined_data.空气质量等级(i) = "二级";

        combined_data.等级描述(i) = "良";

    elseif aqi <= 150

        combined_data.空气质量等级(i) = "三级";

        combined_data.等级描述(i) = "轻度污染";

    elseif aqi <= 200

        combined_data.空气质量等级(i) = "四级";

        combined_data.等级描述(i) = "中度污染";

    elseif aqi <= 300

        combined_data.空气质量等级(i) = "五级";

        combined_data.等级描述(i) = "重度污染";

    else

        combined_data.空气质量等级(i) = "六级";

        combined_data.等级描述(i) = "严重污染";

    end

end
步骤5: 数据分析和可视化
5.1 按监测站统计AQI平均值
Matlab 复制代码
station_aqi = groupsummary(combined_data, '监测站ID', 'mean', 'AQI');

station_aqi = outerjoin(station_info, station_aqi, 'Keys', '监测站ID');
5.2 按空气质量等级统计记录数
Matlab 复制代码
level_counts = groupcounts(combined_data, '等级描述');
5.3 按首要污染物统计记录数
Matlab 复制代码
pollutant_counts = groupcounts(combined_data, '首要污染物');
5.4 按小时统计平均AQI
Matlab 复制代码
combined_data.小时 = hour(combined_data.时间戳);

hourly_aqi = groupsummary(combined_data, '小时', 'mean', 'AQI');
5.5 可视化

5.5.1 各监测站平均AQI

Matlab 复制代码
figure;

bar(station_aqi.mean_AQI);

title('各监测站平均AQI');

xlabel('监测站');

ylabel('AQI');

xticks(1:5);

xticklabels(station_aqi.监测站名称);

xtickangle(45);

5.5.2 空气质量等级分布

Matlab 复制代码
figure;

pie(level_counts.Percent, level_counts.等级描述);

title('空气质量等级分布');

5.5.3 首要污染物分布

Matlab 复制代码
figure;

pie(pollutant_counts.Percent, pollutant_counts.首要污染物);

title('首要污染物分布');

5.5.4 小时平均AQI变化

Matlab 复制代码
figure;

plot(hourly_aqi.小时, hourly_aqi.mean_AQI, '-o', 'LineWidth', 2);

title('小时平均AQI变化');

xlabel('小时');

ylabel('AQI');

grid on;

xticks(0:23);

5.5.5 各监测站AQI时间序列

Matlab 复制代码
figure;

for s = 1:5

    station_id = station_info.监测站ID(s);

    station_name = station_info.监测站名称{s};

    station_mask = strcmp(combined_data.监测站ID, station_id);

    station_data_subset = combined_data(station_mask, :);

    % 按时间排序

    station_data_subset = sortrows(station_data_subset, '时间戳');

    % 每天取一个平均值点(减少数据量)

    daily_data = groupsummary(station_data_subset, '时间戳', 'mean', 'AQI');

    plot(daily_data.时间戳, daily_data.mean_AQI, 'LineWidth', 2);

    hold on;

end

title('各监测站日均AQI时间序列');

xlabel('日期');

ylabel('AQI');

legend(station_info.监测站名称, 'Location', 'best');

grid on;

xtickangle(45);
步骤6: 导出数据
Matlab 复制代码
% writetable(combined_data, '同步空气质量数据.xlsx');

% writetable(station_aqi, '监测站AQI统计.xlsx');

% writetable(level_counts, '空气质量等级统计.xlsx');

% writetable(pollutant_counts, '首要污染物统计.xlsx');

% writetable(hourly_aqi, '小时AQI统计.xlsx');
过程
  • 创建了5个空气质量监测站的模拟数据,包括监测站信息和30天的空气质量监测数据
  • 每个监测站记录PM2.5、PM10、SO2、NO2、O3和CO六项指标
  • 不同位置的监测站有不同的污染物特征(如工业区PM2.5、SO2、NO2较高)
  • 模拟了部分监测站有数据缺失的情况
  • 进行了时间表同步:
  1. 创建完整的时间戳序列(所有监测站的时间戳并集)
  2. 为每个监测站创建包含所有时间戳的新表格,缺失值用NaN填充
  3. 合并所有监测站的数据
  • 处理缺失值:
  1. 统计各指标的缺失值情况
  2. 使用线性插值方法处理缺失值
  3. 再次统计缺失值情况,验证处理效果
  • 计算空气质量指数(AQI):
  • 定义各指标的浓度限值和对应的IAQI计算函数
  • 计算各指标的IAQI(个体空气质量指数)
  • 计算AQI(取各指标IAQI的最大值)
  • 确定首要污染物(IAQI最大的指标)
  • 确定空气质量等级和描述
  • 进行了数据分析和可视化:
  • 按监测站统计AQI平均值
  • 按空气质量等级和首要污染物统计记录数
  • 按小时统计平均AQI
  • 通过多种图表展示分析结果:各监测站平均AQI条形图、空气质量等级和首要污染物分布饼图、小时平均AQI变化折线图、各监测站AQI时间序列图
相关推荐
AAIshangyanxiu3 小时前
【案例教程】生态碳汇涡度通量数据质量控制、缺失插补、可视化分析、光敏感性分析、温度敏感性分析、数据风浪区分析
matlab·涡度通量·生态碳汇
学c语言的枫子3 小时前
数据结构——基本查找算法
算法
yanqiaofanhua4 小时前
C语言自学--自定义类型:结构体
c语言·开发语言·算法
知识分享小能手4 小时前
微信小程序入门学习教程,从入门到精通,微信小程序页面制作(2)
前端·javascript·学习·微信小程序·小程序·前端框架·notepad++
sali-tec4 小时前
C# 基于halcon的视觉工作流-章39-OCR识别
开发语言·图像处理·算法·计算机视觉·c#·ocr
芒克芒克4 小时前
LeetCode 面试经典 150 题之判断子序列解题详解
算法
.鸣4 小时前
idea学习日记10: 字符串相关类的底层原理
java·学习
兮山与4 小时前
算法1.0
算法
蓝桉~MLGT4 小时前
Python学习历程——基础语法(print打印、变量、运算)
开发语言·python·学习