鱼C论坛

 找回密码
 立即注册
查看: 1443|回复: 2

[已解决]matlab代码

[复制链接]
发表于 2023-4-28 00:53:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
% 加载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), [2, 1, 3]), 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    = [1297320  1954776]
nc描述里面范围好像应该是从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年的小时数,然后再根据时间范围限制数据的选择。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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), [2, 1, 3]), 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,那么现在应该会正确处理这些年份。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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年的小时数,然后再根据时间范围限制数据的选择。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 21:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表