聆風祈 发表于 2023-4-28 00:53:16

matlab代码

% 加载nc文件
filename = 'C:\Users\聆風祈\Desktop\论文\数据\air.mon.mean.nc';

% 获取经度、纬度、时间和气温信息
lon = ncread(filename, 'lon');
lat = ncread(filename, 'lat');
time = ncread(filename, 'time');
air = ncread(filename, 'air');

% 计算每个时间单位的小时数
time_units = ncreadatt(filename, 'time', 'units');
hour_str = regexp(time_units, '\d+', 'match');
time_hours = str2double(hour_str{1}) / 24;

% 计算逐年平均气温
start_year = str2double(regexp(time_units, '\d{4}', 'match'));
years = start_year + unique(floor((time - time(1)) / (365 * time_hours)));
num_years = length(years);
annual_avg_temp = zeros(length(lat), length(lon), num_years);

for i = 1:num_years
    year = years(i);
    start_time = (year - start_year) * 365 * time_hours + 1;
    end_time = start_time + 364 * time_hours;
    if end_time > length(time) % 防止超出时间范围
      end_time = length(time);
    end
    annual_avg_temp(:, :, i) = mean(permute(air(:, :, start_time:end_time), ), 3);
end

% 输出结果到Excel文件
excel_filename = 'Annual_Avg_Temperature.xlsx';

for i = 1:num_years
    year = years(i);
    sheet_name = sprintf('Year %d', year);
    % 创建更短的经度和纬度字符串
    lon_str = cellstr(sprintfc('Lon%.1f', lon));
    lat_str = cellstr(sprintfc('Lat%.1f', lat));
    T = array2table(annual_avg_temp(:, :, i), 'VariableNames', lon_str, 'RowNames', lat_str);
    writetable(T, excel_filename, 'Sheet', sheet_name, 'WriteRowNames', true);
end

disp('已将年平均气温按经纬度分布保存到Excel文件。');

大佬,上面这个代码跑出来只有1800一年的数据,后面工作表都是空白的
time
         Size:       901x1
         Dimensions: time
         Datatype:   double
         Attributes:
                     long_name       = 'Time'
                     delta_t         = '0000-01-00 00:00:00'
                     avg_period      = '0000-01-00 00:00:00'
                     prev_avg_period = '0000-00-01 00:00:00'
                     standard_name   = 'time'
                     axis            = 'T'
                     units         = 'hours since 1800-01-01 00:00:0.0'
                     actual_range    =
nc描述里面范围好像应该是从1948还是1949才开始

isdkz 发表于 2023-4-28 01:07:00

从代码中可以看出,处理时间序列时存在一些问题。首先,我们需要纠正计算年份的方法。我们需要找到数据集的开始年份,然后根据时间序列的长度计算其他年份。此外,我们还需要正确处理闰年。以下是修改后的代码:

% 加载nc文件
filename = 'C:\Users\聆風祈\Desktop\论文\数据\air.mon.mean.nc';

% 获取经度、纬度、时间和气温信息
lon = ncread(filename, 'lon');
lat = ncread(filename, 'lat');
time = ncread(filename, 'time');
air = ncread(filename, 'air');

% 计算每个时间单位的小时数
time_units = ncreadatt(filename, 'time', 'units');
hour_str = regexp(time_units, '\d+', 'match');
time_hours = str2double(hour_str{1}) / 24;

% 计算起始年份
start_year = str2double(regexp(time_units, '\d{4}', 'match'));

% 计算年份数
num_years = ceil((length(time) * time_hours) / (365 * 24));
years = start_year:(start_year + num_years - 1);

annual_avg_temp = zeros(length(lat), length(lon), num_years);

% 计算逐年平均气温
current_time = 1;
for i = 1:num_years
    year = years(i);
    days_in_year = 365 + (mod(year, 4) == 0 & (mod(year, 100) ~= 0 | mod(year, 400) == 0));
    end_time = current_time + days_in_year * time_hours - 1;
    if end_time > length(time) % 防止超出时间范围
      end_time = length(time);
    end
    annual_avg_temp(:, :, i) = mean(permute(air(:, :, current_time:end_time), ), 3);
    current_time = end_time + 1;
end

% 输出结果到Excel文件
excel_filename = 'Annual_Avg_Temperature.xlsx';

for i = 1:num_years
    year = years(i);
    sheet_name = sprintf('Year %d', year);
    % 创建更短的经度和纬度字符串
    lon_str = cellstr(sprintfc('Lon%.1f', lon));
    lat_str = cellstr(sprintfc('Lat%.1f', lat));
    T = array2table(annual_avg_temp(:, :, i), 'VariableNames', lon_str, 'RowNames', lat_str);
    writetable(T, excel_filename, 'Sheet', sheet_name, 'WriteRowNames', true);
end

disp('已将年平均气温按经纬度分布保存到Excel文件。');


这个修改后的代码应该能正确处理时间序列,并为每一年生成相应的工作表。如果数据集的开始年份确实是1948或1949,那么现在应该会正确处理这些年份。

陶远航 发表于 2023-4-29 11:33:24

根据你提供的代码和nc描述信息,可以看出数据中的时间变量time的范围是从1297320到1954776,表示从1800年到2019年的小时数。因此,可以通过以下代码来获取数据的时间范围并限制在1948年以后的数据中:
time_units = ncreadatt(filename, 'time', 'units');
hour_str = regexp(time_units, '\d+', 'match');
time_hours = str2double(hour_str{1}) / 24;

start_year = str2double(regexp(time_units, '\d{4}', 'match'));
start_time = (datenum(1948,1,1) - datenum(start_year,1,1)) * 365 * time_hours + 1;
end_time = length(time);
if time(end_time) > datenum(2019,12,31)*24 % 防止超出时间范围
    end_time = find(time < datenum(2019,12,31)*24, 1, 'last');
end

time = time(start_time:end_time);
air = air(:, :, start_time:end_time);

这里使用了MATLAB中的datenum函数来将日期转换为从公元0年1月1日到该日期的天数,从而可以计算出从1800年到1948年的小时数,然后再根据时间范围限制数据的选择。
页: [1]
查看完整版本: matlab代码