风能资源评估是风电项目开发中最基础也最关键的环节。作为从业12年的风资源工程师,我处理过上百个气象塔数据集,深知原始数据质量直接决定项目成败。这次我将分享一套完整的Matlab数据处理流程,从原始数据导入到最终评估报告生成,包含那些教科书上不会写的实战技巧。
气象塔数据通常以10分钟为间隔记录风速、风向、温度等参数,一个完整年度的数据量约5万行。这些看似规整的表格数据在实际处理时会遇到传感器故障、数据缺失、异常值等各种"坑"。下面这套方法经过30+个实际项目验证,能高效产出可靠的风资源分析结果。
常见的气象塔数据格式包括:
以某欧洲品牌记录仪输出的CSV为例,其典型结构如下:
csv复制TIMESTAMP,WS_50m,WD_50m,WS_30m,WD_30m,T_2m
2023-01-01 00:00:00,5.32,187,4.87,185,12.3
2023-01-01 00:10:00,5.41,189,4.92,186,12.1
关键点:必须确认时间戳格式是否含时区信息,风速单位是m/s还是km/h(国内项目常见坑)
推荐使用R2020a及以上版本,必备工具箱:
matlab复制pkg load statistics % 统计工具箱
pkg load signal % 信号处理工具箱
初始化脚本建议包含这些参数:
matlab复制config = struct();
config.sampling_rate = 10; % 分钟
config.heights = [30, 50, 80]; % 测风高度层
config.valid_range = struct(...
'ws', [0.5, 40], ... % 风速合理范围(m/s)
'wd', [0, 360], ... % 风向角度范围
't', [-30, 50]); % 温度范围(℃)
针对不同格式的统一读取接口:
matlab复制function data = read_meteo_data(filename)
[~,~,ext] = fileparts(filename);
switch lower(ext)
case '.csv'
opts = detectImportOptions(filename);
opts.VariableTypes = repmat({'double'},1,length(opts.VariableNames));
opts.VariableTypes{1} = 'datetime';
data = readtable(filename, opts);
case '.dat'
data = parse_binary_file(filename); % 自定义解析函数
otherwise
error('Unsupported file format');
end
% 统一字段命名规范
data.Properties.VariableNames = regexprep(...
data.Properties.VariableNames, '\W', '_');
end
实施三级质检流程:
第一级 - 范围检查
matlab复制function [clean_data, flags] = range_check(raw_data, config)
flags = zeros(height(raw_data),1);
for i = 1:height(raw_data)
if raw_data.WS_50m(i) < config.valid_range.ws(1) || ...
raw_data.WS_50m(i) > config.valid_range.ws(2)
flags(i) = 1; % 标记异常
end
% 其他参数检查...
end
clean_data = raw_data(flags==0,:);
end
第二级 - 变化率检查
风速10分钟变化超过15m/s的物理不可行数据
第三级 - 相关性检查
不同高度层风速应满足垂直变化规律
实战经验:冬季低温时超声波测风仪可能出现虚假高风速,需结合温度数据特殊处理
采用最大似然估计拟合Weibull分布:
matlab复制function [A, k] = weibull_fit(ws_data)
% 消除零值避免拟合失败
ws_data = ws_data(ws_data > 0.1);
phat = wblfit(ws_data);
A = phat(1); % 尺度参数
k = phat(2); % 形状参数
% 可视化验证
figure;
histogram(ws_data,'Normalization','pdf');
hold on;
x = linspace(min(ws_data),max(ws_data),100);
plot(x,wblpdf(x,A,k),'LineWidth',2);
title('Weibull Distribution Fit');
end
16方位角风向频率可视化:
matlab复制function wind_rose(wd_data)
edges = 0:22.5:360;
count = histcounts(wd_data, edges);
% 极坐标绘图
theta = deg2rad(edges(1:end-1)+11.25);
polarplot([theta theta(1)], [count count(1)], 'r-');
thetaticklabels({'N','NNE','NE','ENE','E','ESE','SE','SSE',...
'S','SSW','SW','WSW','W','WNW','NW','NNW'});
end
按IEC标准计算各高度层湍流:
matlab复制function TI = turbulence_intensity(ws_data)
sigma = std(ws_data);
mean_ws = mean(ws_data);
TI = sigma / mean_ws;
% 按风速区间分组计算
bins = 0:1:25;
TI_profile = zeros(length(bins)-1,1);
for i = 1:length(bins)-1
idx = ws_data >= bins(i) & ws_data < bins(i+1);
if sum(idx) > 100 % 确保足够样本
TI_profile(i) = std(ws_data(idx))/mean(ws_data(idx));
end
end
end
采用时间序列预测方法处理缺失数据:
matlab复制function filled_data = fill_missing(data, var_name)
t = hours(data.TIMESTAMP - data.TIMESTAMP(1));
y = data.(var_name);
% 创建时间序列模型
mdl = fitlm(t, y, 'y ~ 1 + t + sin(2*pi*t/144) + cos(2*pi*t/144)');
% 预测缺失值
missing_idx = isnan(y);
filled_data = data;
filled_data.(var_name)(missing_idx) = predict(mdl, t(missing_idx));
end
使用对数律+稳定度修正:
matlab复制function ws_80m = vertical_extrapolation(ws_50m, ws_30m, t_data)
z0 = 0.2; % 粗糙度长度初值
z_ref = [30, 50];
% 迭代计算z0
for iter = 1:10
u_star = (ws_50m - ws_30m) ./ log(50/z0) - log(30/z0);
z0_new = exp(mean(log(ws_50m ./ u_star)));
if abs(z0_new - z0) < 1e-3
break;
end
z0 = z0_new;
end
% 考虑大气稳定度修正
L = monin_obukhov_length(t_data, ws_50m);
psi = stability_correction(80, z0, L);
ws_80m = ws_50m .* (log(80/z0) - psi) ./ (log(50/z0) - psi);
end
matlab复制function create_summary_table(data, outfile)
metrics = {
'年平均风速', mean(data.WS_50m);
'Weibull A参数', weibull_fit(data.WS_50m);
'湍流强度', turbulence_intensity(data.WS_50m);
'主风向', mode(round(data.WD_50m/22.5)*22.5)
};
fid = fopen(outfile, 'w');
fprintf(fid, '\\begin{tabular}{|l|r|}\\n');
fprintf(fid, '\\hline\\n');
fprintf(fid, '指标 & 数值 \\\\\\n');
fprintf(fid, '\\hline\\n');
for i = 1:size(metrics,1)
fprintf(fid, '%s & %.2f \\\\\\n', metrics{i,1}, metrics{i,2});
end
fprintf(fid, '\\hline\\n\\end{tabular}');
fclose(fid);
end
结合MATLAB Report Generator工具包:
matlab复制import mlreportgen.report.*
import mlreportgen.dom.*
rpt = Report('Wind_Assessment','pdf');
chap = Chapter('风资源评估结果');
add(rpt,chap);
% 添加关键图表
fig = Figure(weibull_plot);
fig.Snapshot.Caption = '风速Weibull分布拟合';
add(chap,fig);
% 添加数据表格
tbl = Table(metrics);
tbl.Style = {RowSep('solid'), ColSep('solid')};
add(chap,tbl);
close(rpt);
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| Weibull拟合失败 | 数据含零值 | 过滤<0.1m/s的数据点 |
| 风向玫瑰图错位 | 角度单位混淆 | 统一转换为0-360度范围 |
| 垂直外推异常 | 粗糙度不合理 | 限制z0在0.001-1.0之间 |
| 数据周期性缺失 | 传感器结冰 | 结合温度数据筛选 |
处理全年数据时(约5万行):
tall array处理大数据:matlab复制ds = tabularTextDatastore('data.csv');
tt = tall(ds);
A = gather(mean(tt.WS_50m));
matlab复制parfor i = 1:12
monthly_data = data(month(data.TIMESTAMP)==i,:);
% 分月处理...
end
matlab复制results = zeros(height(data),1); % 预先分配
for i = 1:height(data)
results(i) = complex_calculation(data(i,:));
end
与其他参考站数据关联分析:
matlab复制function [corrected_ws] = mcp_correction(target_ws, ref_ws)
% 建立线性回归模型
mdl = fitlm(ref_ws, target_ws);
% 获取长期修正系数
alpha = mdl.Coefficients.Estimate(2);
beta = mdl.Coefficients.Estimate(1);
% 应用修正
corrected_ws = alpha * target_ws + beta;
end
结合风机功率曲线模拟:
matlab复制function AEP = energy_estimation(ws_data, power_curve)
% 功率曲线插值
pc_ws = power_curve(:,1);
pc_kw = power_curve(:,2);
% 计算每个风速点的发电量
hourly_energy = interp1(pc_ws, pc_kw, ws_data, 'linear', 0);
% 年发电量(kWh)
AEP = sum(hourly_energy) * (6/60); % 10分钟数据换算为小时
end
这套代码框架在我经手的海上风电项目中,将数据处理效率提升了3倍以上。特别提醒:不同品牌测风设备的原始数据格式差异很大,建议先对数据采集器进行现场校验,避免后期数据处理时发现系统偏差。最新的IEC 61400-15标准对数据处理提出了更严格的要求,后续可以加入标准合规性自动检查模块。