Skip to content

关于在 Matlab 中读取和计算 Excel 表的数据

Published: at 00:00

前言

在维护一个用 Matlab 编写的金融量化项目时,数据的获取和处理通常是至关重要的一环。在这个项目中,我主要使用两种数据源:Mat 文件和 Excel 表格文件。Mat 文件是 Matlab 的一种标准数据格式,而 Excel 表格则是广泛应用于各种数据的常见格式之一。

在本文中,我将分享一些读取 Excel 表格数据的相关技巧和用法,旨在帮助您更高效地处理数据,并在项目中取得更好的结果。

Excel 表数据

这里自行构造了一个有A到G列的数据,文件名为:data.xlsx,数据如下:

ABCDEFG
SH.ZCE2745272327522774-311
SHL.ZCE2745272327522774-311
CJL.ZCE14175142001415014150-3501
CJ.ZCE14400144901439514395-3751
UR.ZCE2161216021502150-1121
URL.ZCE2277229322622262-731
TA.ZCE5900588858905952-1120
MAL.ZCE2354235023812404-130
CFL.ZCE15560155451552015620-1101
SRL.ZCE636563726363640081
RSL.ZCE0609060266099-521
LRL.ZCE023600000
URL.ZCE7833782878347859-590
MA.ZCE238623822387240051
RIL.ZCE024790000
RS.ZCE0608260726099-170
ZC.ZCE0801.40000
LR.ZCE023600000
URL.ZCE7788778778127812-401
WHL.ZCE031980000
PM.ZCE031220000
URL.ZCE6308632162906338-81
RI.ZCE024790000
SFL.ZCE0667266986698-4601
RML.ZCE2736276227002700-801

Matlab 代码和示例

dataFilePath = './data.xlsx';

%% 加载文件
% 加载 excel 文件
dataTable = readtable(dataFilePath);


%% 读取数据
disp(dataTable);

% 行数和列数
[numRows, numCols] = size(dataTable);

disp('行数:');
fprintf("rows num: %d\n", numRows);

disp('列数:');
fprintf("cols num: %d\n", numCols);

% 所有列名
columnNames = dataTable.Properties.VariableNames;
disp('所有列名:');
disp(columnNames);

disp('判断 H 列是否存在:');
disp(ismember('H', columnNames));

% 获取对应列数据
disp('获取 A 列所有值:');
disp(dataTable.A);
disp('获取 B 列所有值:');
disp(dataTable.B);
disp('获取 A, B, E, F 列的数据:');
disp(dataTable(:, {'A', 'B', 'E', 'F'}));

% 获取对应行数据, 在 MATLAB 中,行号从 1 开始
disp('获取第 5 行所有值:');
disp(dataTable(5,:));
disp('获取第 5 行到第 10 行的数据:');
disp(dataTable(5:10,:));

% 获取对应行对应列的数据
disp('获取第 5 行 E 列的值:');
disp(dataTable{5, 'E'});

disp('获取第 5 到 9 行的 A, E, F 列的数据:');
disp(dataTable(5:9, {'A', 'E', 'F'}));

disp('获取 A 列等于 URL.ZCE 的所有行数据:')
disp(dataTable(dataTable.A == "URL.ZCE", :));

disp('获取 A 列等于 URL.ZCE , B 列最大的行数据:');
subsetData = dataTable(dataTable.A == "URL.ZCE", :);
[value, index] = max(subsetData.B);
disp(subsetData(index, :));

disp('获取 A 列等于 URL.ZCE , C 列最小的行数据:');
subsetData = dataTable(dataTable.A == "URL.ZCE", :);
[minValue, minIndex] = min(subsetData.C);
disp(subsetData(minIndex, :));

disp('获取 B 列大于 100 的所有数据:');
disp(dataTable(dataTable.B > 100, :));

disp('获取 F 列小于 0 的所有数据:');
disp(dataTable(dataTable.F < 0, :));

disp('获取 B 列大于 100 和 F 列小于 0 的所有数据:');
disp(dataTable((dataTable.B > 100) & (dataTable.F < 0), :));


%% 排序
% 升序
disp('按 A 列排序:');
disp(sortrows(dataTable, 'A'));

% 降序
disp('按 B 列降序:');
disp(sortrows(dataTable, 'B', 'descend'));

% 组合升降度
disp('按 A 列升序 C 列降序:');
disp(sortrows(dataTable, {'A', 'C'}, {'ascend', 'descend'}));


%% 统计
% 计算总和
disp('对 C 列求和:');
disp(sum(dataTable.C));

% 计算最大值
disp('对 E 列求最大值:');
disp(max(dataTable.E));

% 计算最小值
disp('对 F 列求最小值:');
disp(min(dataTable.F));

% 计算平均数
disp('对 B 列求平均数:');
disp(mean(dataTable.B));

% 计算方差
disp('对 D 列求方差:');
disp(var(dataTable.D));

% 计算标准差
disp('对 D 列求标准差:');
disp(std(dataTable.D));

%% 分组聚合
disp('按 A 列分组,找出有多行数据的对应行:');
summaryData = groupsummary(dataTable, 'A');
groupsWithMultipleRows = summaryData(summaryData.GroupCount > 1, :);
rowsWithMultipleData = summaryData(ismember(summaryData.A, groupsWithMultipleRows.A), :);
disp(rowsWithMultipleData);

disp('按 A 列分组,对 B 列进行求和:');
disp(groupsummary(dataTable, 'A', 'sum', 'B'));

disp('按 A 列分组,对 B 列进行求和,过滤大于 2000 的数据:');
summaryData = groupsummary(dataTable, 'A', 'sum', 'B');
filteredData = summaryData(summaryData.sum_B > 2000, :);
disp(filteredData);

disp('按 A 列分组,对 B 列进行求和,过滤大于 2000 的数据,并按求和数据降序排列:');
summaryData = groupsummary(dataTable, 'A', 'sum', 'B');
filteredData = summaryData(summaryData.sum_B > 2000, :);
disp(sortrows(filteredData, 'sum_B', 'descend'));