前言
在维护一个用 Matlab 编写的金融量化项目时,数据的获取和处理通常是至关重要的一环。在这个项目中,我主要使用两种数据源:Mat 文件和 Excel 表格文件。Mat 文件是 Matlab 的一种标准数据格式,而 Excel 表格则是广泛应用于各种数据的常见格式之一。
在本文中,我将分享一些读取 Excel 表格数据的相关技巧和用法,旨在帮助您更高效地处理数据,并在项目中取得更好的结果。
Excel 表数据
这里自行构造了一个有A到G列的数据,文件名为:data.xlsx,数据如下:
A | B | C | D | E | F | G |
---|---|---|---|---|---|---|
SH.ZCE | 2745 | 2723 | 2752 | 2774 | -31 | 1 |
SHL.ZCE | 2745 | 2723 | 2752 | 2774 | -31 | 1 |
CJL.ZCE | 14175 | 14200 | 14150 | 14150 | -350 | 1 |
CJ.ZCE | 14400 | 14490 | 14395 | 14395 | -375 | 1 |
UR.ZCE | 2161 | 2160 | 2150 | 2150 | -112 | 1 |
URL.ZCE | 2277 | 2293 | 2262 | 2262 | -73 | 1 |
TA.ZCE | 5900 | 5888 | 5890 | 5952 | -112 | 0 |
MAL.ZCE | 2354 | 2350 | 2381 | 2404 | -13 | 0 |
CFL.ZCE | 15560 | 15545 | 15520 | 15620 | -110 | 1 |
SRL.ZCE | 6365 | 6372 | 6363 | 6400 | 8 | 1 |
RSL.ZCE | 0 | 6090 | 6026 | 6099 | -52 | 1 |
LRL.ZCE | 0 | 2360 | 0 | 0 | 0 | 0 |
URL.ZCE | 7833 | 7828 | 7834 | 7859 | -59 | 0 |
MA.ZCE | 2386 | 2382 | 2387 | 2400 | 5 | 1 |
RIL.ZCE | 0 | 2479 | 0 | 0 | 0 | 0 |
RS.ZCE | 0 | 6082 | 6072 | 6099 | -17 | 0 |
ZC.ZCE | 0 | 801.4 | 0 | 0 | 0 | 0 |
LR.ZCE | 0 | 2360 | 0 | 0 | 0 | 0 |
URL.ZCE | 7788 | 7787 | 7812 | 7812 | -40 | 1 |
WHL.ZCE | 0 | 3198 | 0 | 0 | 0 | 0 |
PM.ZCE | 0 | 3122 | 0 | 0 | 0 | 0 |
URL.ZCE | 6308 | 6321 | 6290 | 6338 | -8 | 1 |
RI.ZCE | 0 | 2479 | 0 | 0 | 0 | 0 |
SFL.ZCE | 0 | 6672 | 6698 | 6698 | -460 | 1 |
RML.ZCE | 2736 | 2762 | 2700 | 2700 | -80 | 1 |
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'));