MATLAB 数据导入(ImportData)

数据导入是指将存储在外部文件中的数据加载到MATLAB工作空间中的过程。

MATLAB支持导入多种格式的数据文件,包括:

  • 文本文件:.txt、.csv、.dat等
  • 电子表格:.xlsx、.xls等
  • 科学数据格式:.mat、.h5、.nc等
  • 图像文件:.jpg、.png、.tiff等
  • 音频文件:.wav、.mp3等

MATLAB 提供了丰富的数据 I/O 函数,支持多种文件格式,包括文本文件、Excel 文件、图像文件、音频文件等,方便用户根据不同的需求选择合适的导入方法。

importdata函数

importdata函数是MATLAB中最通用的数据导入函数,能够自动识别文件格式并采用相应的导入策略。这使得用户在导入数据时无需手动指定文件格式,大大提高了数据导入的效率。

importdata功能允许加载不同格式的各种数据文件。它具有以下五种形式

功能 语句
从指定文件导入数据到数组A A = importdata(filename)
从系统剪贴板而不是文件加载数据。 A = importdata(‘-pastespecial’)
指定列分隔符导入 **A = importdata(___, delimiterIn)**
指定分隔符和头行数导入 **A = importdata(___, delimiterIn, headerlinesIn)**
返回检测到的分隔符和头行信息 **[A, delimiterOut, headerlinesOut] = importdata(___)**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
% ===== 示例1:基本文本文件导入 =====
% 假设有一个名为'sample_data.txt'的文件,内容如下:
% Name, Age, Score
% Alice, 25, 85.5
% Bob, 30, 92.3
% Charlie, 28, 78.9

% 导入数据
data = importdata('sample_data.txt');

% 检查导入结果的结构
if isstruct(data)
fprintf('数据类型:结构体\n');
fprintf('数值数据维度:%d x %d\n', size(data.data));
fprintf('文本数据行数:%d\n', length(data.textdata));

% 显示数值数据
disp('数值数据:');
disp(data.data);

% 显示文本数据(包括头行)
disp('文本数据:');
disp(data.textdata);
else
disp('导入的是纯数值数据');
disp(data);
end

% ===== 示例2:CSV文件导入 =====
% 创建示例CSV文件
csvData = [1, 2, 3; 4, 5, 6; 7, 8, 9];
csvwrite('example.csv', csvData);

% 导入CSV文件
importedCSV = importdata('example.csv');
fprintf('CSV数据:\n');
disp(importedCSV);

% ===== 示例3:指定分隔符导入 =====
% 创建用制表符分隔的文件
tabData = ['1' char(9) '2' char(9) '3' newline ...
'4' char(9) '5' char(9) '6' newline ...
'7' char(9) '8' char(9) '9'];
fid = fopen('tab_separated.txt', 'w');
fprintf(fid, '%s', tabData);
fclose(fid);

% 使用制表符作为分隔符导入
tabImported = importdata('tab_separated.txt', '\t');
fprintf('制表符分隔的数据:\n');
disp(tabImported);

% ===== 示例4:处理带头行的文件 =====
% 创建带头行的数据文件
headerData = ['Temperature,Humidity,Pressure' newline ...
'Unit: C,Unit: %,Unit: hPa' newline ...
'25.5,60.2,1013.25' newline ...
'26.8,58.7,1012.80' newline ...
'24.9,62.1,1014.15'];
fid = fopen('weather_data.txt', 'w');
fprintf(fid, '%s', headerData);
fclose(fid);

% 导入时指定跳过前2行头信息
[weatherData, delimiter, headerLines] = importdata('weather_data.txt', ',', 2);
fprintf('检测到的分隔符:%s\n', delimiter);
fprintf('检测到的头行数:%d\n', headerLines);
fprintf('天气数据:\n');
disp(weatherData);

Excel文件导入

Excel文件是最常见的数据存储格式之一,MATLAB提供了多种方法来处理Excel文件。

使用readtable函数

readtable 函数是推荐的 Excel 文件导入方法,它可以将 Excel 文件中的数据读取为表格形式,方便后续的数据处理和分析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
% ===== Excel文件导入示例 =====

% 方法1:使用readtable(推荐)
% 创建示例Excel数据
studentData = table(['Alice'; 'Bob'; 'Charlie'], [25; 30; 28], [85.5; 92.3; 78.9], ...
'VariableNames', {'Name', 'Age', 'Score'});
writetable(studentData, 'students.xlsx');

% 读取Excel文件
students = readtable('students.xlsx');
fprintf('学生数据表:\n');
disp(students);

% 访问特定列
names = students.Name;
ages = students.Age;
scores = students.Score;

fprintf('平均年龄:%.1f\n', mean(ages));
fprintf('平均分数:%.1f\n', mean(scores));

% 方法2:使用xlsread(较老的方法)
[numData, textData, rawData] = xlsread('students.xlsx');
fprintf('数值数据:\n');
disp(numData);
fprintf('文本数据:\n');
disp(textData);

% 方法3:读取特定工作表和范围
% 假设Excel文件有多个工作表
writetable(studentData, 'multi_sheet.xlsx', 'Sheet', 'Sheet1');
writetable(studentData, 'multi_sheet.xlsx', 'Sheet', 'BackupData');

% 读取指定工作表
sheet1Data = readtable('multi_sheet.xlsx', 'Sheet', 'Sheet1');
backupData = readtable('multi_sheet.xlsx', 'Sheet', 'BackupData');

% 读取指定范围
rangeData = readtable('students.xlsx', 'Range', 'A1:C3');
fprintf('指定范围的数据:\n');
disp(rangeData);

专用导入函数

MATLAB 为不同类型的文件提供了专用的导入函数,这些函数可以更高效地处理特定类型的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
% 文本文件
data = readtable('data.csv', 'Delimiter', ',', 'HeaderLines', 1);

% Excel文件
[num, txt, raw] = xlsread('data.xlsx', 'Sheet1', 'A1:C10');

% 图像文件
img = imread('image.jpg');
imshow(img);

% 音频文件
[y, Fs] = audioread('sound.wav');
sound(y, Fs);

以文本文件专用函数为例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
% ===== 文本文件导入的其他方法 =====

% readmatrix - 读取数值矩阵
numMatrix = [1, 2, 3; 4, 5, 6; 7, 8, 9];
writematrix(numMatrix, 'matrix_data.txt');
importedMatrix = readmatrix('matrix_data.txt');
fprintf('导入的矩阵:\n');
disp(importedMatrix);

% readcell - 读取混合数据为元胞数组
mixedData = {'Name', 'Age', 'City'; 'Alice', 25, 'NYC'; 'Bob', 30, 'LA'};
writecell(mixedData, 'mixed_data.txt');
importedCell = readcell('mixed_data.txt');
fprintf('混合数据:\n');
disp(importedCell);

% textscan - 格式化文本读取
fid = fopen('formatted_data.txt', 'w');
fprintf(fid, 'Alice 25 85.5\nBob 30 92.3\nCharlie 28 78.9\n');
fclose(fid);

fid = fopen('formatted_data.txt', 'r');
scannedData = textscan(fid, '%s %d %f');
fclose(fid);

fprintf('格式化读取结果:\n');
fprintf('姓名:'); disp(scannedData{1}');
fprintf('年龄:'); disp(scannedData{2}');
fprintf('分数:'); disp(scannedData{3}');

底层文件I / O

importdata函数是一个高级函数。MATLAB中的底层文件I/O函数允许对文件的读写数据进行最大程度的控制。但是,这些函数需要更详细的文件信息才能有效地工作。

MATLAB为字节或字符级别的读写操作提供以下函数

函数 描述
fclose 关闭一个或所有打开的文件
feof 文件结尾测试
ferror 有关文件I/O错误的信息
fgetl 从文件中读取行,删除换行符
fgets 从文件中读取行,保留换行符
fopen 打开文件,或获取有关打开文件的信息
fprintf 将数据写入文本文件
fread 从二进制文件读取数据
frewind 将文件位置指示器移动到打开文件的开头
fscanf 从文本文件读取数据
fseek 移动到文件中的指定位置
ftell 在打开文件中的位置
fwrite 将数据写入二进制文件

导入具有底层I / O的文本数据文件

  • MATLAB 提供以下功能用于文本数据文件的底层导入:
    • fscanf 函数读取文本或 ASCII 文件中的格式化数据。可以根据指定的格式字符串从文件中读取数据,例如 '%s %d %f' 表示读取一个字符串、一个整数和一个浮点数。
    • fgetlfgets 的时间,其中,一个换行字符的每一行分离功能读取的文件的一行。fgetl 会去除行末的换行符,而 fgets 会保留换行符。
    • fread 函数读取字节或位级别的数据流。可以用于读取二进制文件或文本文件的原始字节数据。
1
2
3
4
5
6
7
8
9
10
11
% 底层 I/O 读取文本文件示例
fid = fopen('data.txt', 'r');
if fid ~= -1
while ~feof(fid)
line = fgetl(fid);
disp(line);
end
fclose(fid);
else
error('无法打开文件');
end

MATLAB 数据输出

数据导出(或输出)在 MATLAB 的意思是写入文件。MATLAB 允许您在另一个读取 ASCII 文件的应用程序中使用您的数据。为此,MATLAB 提供了几个数据导出选项。

可以创建以下类型的文件:

  • 数组中的矩形、分隔的 ASCII 数据文件。常用于将数值数据以文本形式保存,方便其他程序读取。
  • 击键的日记(或日志)文件和结果文本输出。可以记录 MATLAB 命令窗口中的操作和输出结果。
  • 使用底层函数(如 fprintf)的专用 ASCII 文件。可以根据需要自定义文件的格式和内容。
  • MEX 文件,用于访问以特定文本文件格式写入的 C / C ++ 或 Fortran 例程。可以在 MATLAB 中调用 C、C++ 或 Fortran 编写的函数。

MATLAB支持多种输出格式,选择合适的格式取决于:

  • 目标应用程序:是否需要被Excel、其他编程语言或特定软件读取
  • 数据特性:数值数据、文本数据还是混合数据
  • 文件大小:是否需要压缩或高效存储
  • 精度要求:是否需要保持完整的数值精度

除此之外,还可以将数据导出到电子表格。

有两种方法可以将数字数组导出为定界的ASCII数据文件

  • 使用save函数并指定-ascii限定符

  • 使用dlmwrite函数

使用save函数输出ASCII文件

save函数配合-ascii选项是输出数值数据最简单的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
% ===== save函数ASCII输出示例 =====

% 创建示例数据
temperatureData = [
25.5, 26.2, 24.8, 27.1, 25.9;
26.8, 27.5, 25.3, 28.2, 26.7;
24.9, 25.6, 23.7, 26.4, 25.1
];

% 基本ASCII保存
save('temperature.txt', 'temperatureData', '-ascii');
fprintf('数据已保存到 temperature.txt\n');

% 验证保存结果
savedData = load('temperature.txt');
fprintf('保存的温度数据:\n');
disp(savedData);

% 高精度保存(16位精度)
preciseData = pi * rand(3, 3);
save('precise_data.txt', 'preciseData', '-ascii', '-double');
fprintf('高精度数据:\n');
disp(preciseData);

% 读取并比较精度
loadedPrecise = load('precise_data.txt');
fprintf('精度差异(应接近0):\n');
disp(abs(preciseData - loadedPrecise));

% 制表符分隔保存
save('tab_separated_output.txt', 'temperatureData', '-ascii', '-tabs');
fprintf('制表符分隔文件已创建\n');

使用dlmwrite函数

dlmwrite函数提供了更多的格式控制选项,特别适合需要自定义分隔符的场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
% ===== dlmwrite函数详细示例 =====

% 创建销售数据示例
salesMatrix = [
1001, 1500, 2000, 1800; % Q1销售额
1200, 1600, 2100, 1900; % Q2销售额
1100, 1400, 1900, 1700; % Q3销售额
1300, 1700, 2200, 2000 % Q4销售额
];

% 基本逗号分隔输出
dlmwrite('sales_comma.csv', salesMatrix, 'delimiter', ',');
fprintf('逗号分隔文件已创建\n');

% 自定义分隔符(分号)
dlmwrite('sales_semicolon.csv', salesMatrix, 'delimiter', ';');
fprintf('分号分隔文件已创建\n');

% 指定精度
dlmwrite('sales_precision.txt', salesMatrix, 'delimiter', '\t', 'precision', 6);
fprintf('高精度制表符分隔文件已创建\n');

% 追加数据到现有文件
newQuarterData = [1400, 1800, 2300, 2100];
dlmwrite('sales_comma.csv', newQuarterData, 'delimiter', ',', '-append');
fprintf('新季度数据已追加\n');

% 验证追加结果
appendedData = csvread('sales_comma.csv');
fprintf('追加后的完整数据:\n');
disp(appendedData);

% 带偏移的写入
dlmwrite('offset_example.txt', [999, 888], 'delimiter', ',', ...
'roffset', 2, 'coffset', 1);
fprintf('带偏移的数据已写入\n');

% 读取验证偏移效果
offsetResult = dlmread('offset_example.txt', ',');
fprintf('偏移写入结果:\n');
disp(offsetResult);

Excel文件输出

Excel输出对于与办公软件交互非常重要,MATLAB提供了多种Excel输出方法。

使用最基本的xlswrite

1
2
data = {'Name','Age'; 'John',28; 'Mary',32};
xlswrite('output.xlsx', data, 'Sheet1', 'A1');

使用writetable函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
% ===== Excel输出综合示例 =====

% 创建完整的业务数据表
employeeData = table();
employeeData.EmployeeID = (1001:1010)';
employeeData.Name = {'Alice Johnson'; 'Bob Smith'; 'Charlie Brown'; 'Diana Prince';
'Edward Norton'; 'Fiona Green'; 'George Lucas'; 'Helen Troy';
'Ivan Petrov'; 'Jane Doe'};
employeeData.Department = categorical({'IT'; 'HR'; 'Finance'; 'IT'; 'Marketing';
'HR'; 'Finance'; 'IT'; 'Marketing'; 'Finance'});
employeeData.Salary = [75000; 68000; 72000; 78000; 65000;
70000; 74000; 80000; 67000; 73000];
employeeData.StartDate = datetime({'2020-01-15'; '2019-03-22'; '2021-07-10'; '2020-11-05';
'2021-02-28'; '2019-09-15'; '2020-06-01'; '2021-04-20';
'2020-08-12'; '2021-01-30'});
employeeData.Performance = [4.2; 3.8; 4.0; 4.5; 3.7; 4.1; 3.9; 4.3; 3.6; 4.0];

% 基本Excel输出
writetable(employeeData, 'employee_data.xlsx');
fprintf('员工数据已保存到Excel文件\n');

% 指定工作表名称
writetable(employeeData, 'company_data.xlsx', 'Sheet', 'Employees');
fprintf('数据已保存到指定工作表\n');

% 多工作表输出
% 按部门分组
departments = unique(employeeData.Department);
for i = 1:length(departments)
deptData = employeeData(employeeData.Department == departments(i), :);
sheetName = char(departments(i));
writetable(deptData, 'department_reports.xlsx', 'Sheet', sheetName);
fprintf('部门 %s 的数据已保存\n', sheetName);
end

% 统计摘要输出
summary_stats = table();
summary_stats.Department = departments;
summary_stats.EmployeeCount = zeros(length(departments), 1);
summary_stats.AvgSalary = zeros(length(departments), 1);
summary_stats.AvgPerformance = zeros(length(departments), 1);

for i = 1:length(departments)
deptData = employeeData(employeeData.Department == departments(i), :);
summary_stats.EmployeeCount(i) = height(deptData);
summary_stats.AvgSalary(i) = mean(deptData.Salary);
summary_stats.AvgPerformance(i) = mean(deptData.Performance);
end

writetable(summary_stats, 'department_reports.xlsx', 'Sheet', 'Summary');
fprintf('部门统计摘要已保存\n');

% 显示摘要
fprintf('部门统计摘要:\n');
disp(summary_stats);

使用writematrix和writecell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
% ===== 矩阵和元胞数组Excel输出 =====

% 数值矩阵输出
correlationMatrix = corrcoef(rand(10, 5));
writematrix(correlationMatrix, 'correlation_analysis.xlsx', 'Sheet', 'Correlation');
fprintf('相关性矩阵已保存\n');

% 元胞数组输出(混合数据类型)
reportData = {
'Metric', 'Q1', 'Q2', 'Q3', 'Q4', 'Total';
'Revenue', 150000, 165000, 180000, 170000, 665000;
'Expenses', 120000, 130000, 140000, 135000, 525000;
'Profit', 30000, 35000, 40000, 35000, 140000;
'Margin %', 20.0, 21.2, 22.2, 20.6, 21.1
};

writecell(reportData, 'quarterly_report.xlsx', 'Sheet', 'Financial Summary');
fprintf('季度报告已保存\n');

% 带格式控制的输出
xlswrite('formatted_output.xlsx', reportData, 'Summary', 'A1');
fprintf('格式化输出完成\n');

专业格式输出

JSON格式输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% ===== JSON格式数据输出 =====

% 创建结构化数据
projectData.project_name = 'Data Analysis Pipeline';
projectData.version = '2.1.0';
projectData.created_date = datestr(now, 'yyyy-mm-dd');
projectData.team_members = {'Alice', 'Bob', 'Charlie'};
projectData.modules = struct('data_import', true, 'analysis', true, 'visualization', false);
projectData.parameters = struct('threshold', 0.05, 'iterations', 1000, 'method', 'regression');

% 转换为JSON并保存
jsonStr = jsonencode(projectData);
fid = fopen('project_config.json', 'w');
fprintf(fid, '%s', jsonStr);
fclose(fid);
fprintf('项目配置已保存为JSON格式\n');

% 美化JSON输出
prettyJson = jsonencode(projectData, 'PrettyPrint', true);
fid = fopen('project_config_pretty.json', 'w');
fprintf(fid, '%s', prettyJson);
fclose(fid);
fprintf('格式化JSON配置已保存\n');

% 显示JSON内容
fprintf('JSON配置内容:\n%s\n', prettyJson);

图像/音频输出

1
2
3
4
5
% 图像
imwrite(img, 'output.png', 'PNG');

% 音频
audiowrite('output.wav', y, Fs);

自定义格式输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
% ===== 自定义格式输出示例 =====

% 创建实验数据
experimentData = struct();
experimentData.experiment_id = 'EXP_2024_001';
experimentData.timestamp = datetime('now');
experimentData.conditions = {'Control', 'Treatment_A', 'Treatment_B'};
experimentData.measurements = rand(3, 10) * 100; % 3个条件,每个10次测量
experimentData.statistics = struct();

% 计算统计信息
for i = 1:length(experimentData.conditions)
condition = experimentData.conditions{i};
data = experimentData.measurements(i, :);
experimentData.statistics.(condition) = struct(...
'mean', mean(data), ...
'std', std(data), ...
'min', min(data), ...
'max', max(data), ...
'n', length(data));
end

% 自定义格式报告输出
fid = fopen('experiment_report.txt', 'w');
fprintf(fid, '实验报告\n');
fprintf(fid, '========================================\n');
fprintf(fid, '实验编号: %s\n', experimentData.experiment_id);
fprintf(fid, '实验时间: %s\n', datestr(experimentData.timestamp));
fprintf(fid, '========================================\n\n');

fprintf(fid, '实验条件和结果:\n');
fprintf(fid, '----------------------------------------\n');
for i = 1:length(experimentData.conditions)
condition = experimentData.conditions{i};
stats = experimentData.statistics.(condition);

fprintf(fid, '\n条件: %s\n', condition);
fprintf(fid, ' 样本数量: %d\n', stats.n);
fprintf(fid, ' 平均值: %.2f\n', stats.mean);
fprintf(fid, ' 标准差: %.2f\n', stats.std);
fprintf(fid, ' 最小值: %.2f\n', stats.min);
fprintf(fid, ' 最大值: %.2f\n', stats.max);

% 输出原始数据
fprintf(fid, ' 原始数据: ');
fprintf(fid, '%.2f ', experimentData.measurements(i, :));
fprintf(fid, '\n');
end

fprintf(fid, '\n========================================\n');
fprintf(fid, '报告生成时间: %s\n', datestr(now));
fclose(fid);

fprintf('实验报告已生成\n');

常见问题

中文乱码处理

在导入包含中文的数据文件时,可能会出现中文乱码的问题。可以通过设置文件的编码格式来解决。

1
2
3
opts = detectImportOptions('data.csv');
opts.Encoding = 'UTF-8'; % 或 'GB2312'
data = readtable('data.csv', opts);

缺失数据处理

在实际数据中,可能会存在缺失值。可以使用 standardizeMissing 函数将特定的值标记为缺失值,然后使用 fillmissing 函数填充缺失值。

1
2
data = standardizeMissing(data, {'NA', '', '.', 'NaN'});
data = fillmissing(data, 'constant', 0); % 用 0 填充缺失值

日期格式转换

在导入包含日期的数据时,可能需要将日期字符串转换为 MATLAB 的日期时间类型。可以使用 detectImportOptions 函数检测导入选项,并使用 setvartype 函数设置日期变量的类型。

1
2
3
opts = detectImportOptions('data.csv');
opts = setvartype(opts, 'Date', 'datetime');
data = readtable('data.csv', opts);

大数据处理

当处理大型数据集时,一次性将整个数据集加载到内存中可能会导致内存不足的问题。可以使用 datastore 函数创建数据存储对象,然后逐块读取数据进行处理。

1
2
3
4
5
6
% 使用 datastore 处理大型数据集
ds = datastore('largefile.csv');
while hasdata(ds)
chunk = read(ds);
% 处理数据块
end

格式对照表

文件类型 导入函数 导出函数 备注
CSV/TXT readtable writetable 推荐处理表格数据
Excel readtable/xlsread writetable/xlswrite 注意Office版本兼容性
图像 imread imwrite 支持多种图像格式
音频 audioread audiowrite 需指定采样率
MAT文件 load save MATLAB专用二进制格式
HDF5 h5read h5write 科学数据常用格式