matlab循环处理nc数据遇到问题

大家好。我想批量读取不同年份的不同月份的数据,但是我发现代码只能读取某一年的end_month的数据。也就是说不管我怎么修改输入年份,读取出来的结果是重复读取“某一年 ”的end_month的结果。比如下面我循环读取了三年(1974-1976年)的数据,那么出来的结果t_2d矩阵里面是一组结果重复记录了3遍。

请问各位问题出在哪里?之前循环月份的时候没问题,现在加入循环年份后就出现这个问题了。我怀疑这个“某一年”是1970年。

clc
clear all;
% 设置循环参数
start_month = 05;
end_month = 08;
start_year = 1974;
end_year = 1976;
% 存储温度指标的变量
avg_t_daily_new = [];

% 循环读取和处理多个nc图像
for year = start_year:end_year     
    for month = start_month:end_month
            % 构建nc图像文件名
            file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc',year,month);
            % 读取温度数据
            t = ncread(file_name, 'TBOT');
            LONGXY = ncread(file_name, 'LONGXY');
            LATIXY = ncread(file_name, 'LATIXY');
            % 获取变量 t 的尺寸信息(依次为:经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time
            [num_lon, num_lat, num_time] = size(t);
            % 重塑矩阵为二维
            t_2d = reshape(t, [], num_time);
            avg_t_daily_new = [avg_t_daily_new, t_2d];
    end
end

这是我的数据情况:

img

发下文件吧还是

基于new bing部分指引作答:
根据您提供的代码,循环年份和月份的逻辑看起来是正确的。问题可能出在数据存储的部分。

在每次循环内,您将t_2d矩阵追加到avg_t_daily_new矩阵中。然而,您的代码中只有一个avg_t_daily_new变量,因此在每次循环追加数据时,实际上是将新的t_2d矩阵附加到了之前的数据后面,导致重复记录。

解决这个问题的方法是在每次循环内创建一个新的avg_t_daily_new变量,以存储该年份的数据。可以使用一个cell数组来存储每年的数据,每个元素都是一个矩阵。修改代码如下:

clc
clear all;
% 设置循环参数
start_month = 05;
end_month = 08;
start_year = 1974;
end_year = 1976;
% 存储温度指标的变量
avg_t_daily_new = cell(end_year - start_year + 1, 1);

% 循环读取和处理多个nc图像
for year = start_year:end_year
    yearly_data = []; % 存储每年的数据
    for month = start_month:end_month
        % 构建nc图像文件名
        file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc', year, month);
        % 读取温度数据
        t = ncread(file_name, 'TBOT');
        LONGXY = ncread(file_name, 'LONGXY');
        LATIXY = ncread(file_name, 'LATIXY');
        % 获取变量 t 的尺寸信息(依次为:经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time
        [num_lon, num_lat, num_time] = size(t);
        % 重塑矩阵为二维
        t_2d = reshape(t, [], num_time);
        yearly_data = [yearly_data, t_2d];
    end
    avg_t_daily_new{year - start_year + 1} = yearly_data;
end

这样,avg_t_daily_new变量将是一个cell数组,每个元素都存储了对应年份的数据。您可以通过索引来访问每个年份的数据,例如avg_t_daily_new{1}将返回第一个年份的数据。

希望这可以解决您的问题!

回答引自chatgpt
问题可能出在 avg_t_daily_new 变量的拼接上,每个循环中 t_2d 矩阵的列数(即 num_time)是相同的,因此拼接时可能会有重复的列。你可以尝试在每次拼接前,先记录前面的列数,然后通过判断当前列数是否等于前面的列数来决定是否继续拼接
在每次拼接时,如果当前列数等于前面的列数,就直接拼接;如果不等,则先在拼接矩阵中添加一些空白列,再拼接当前的 t_2d 矩阵。这样就可以避免重复拼接相同的列了

clc
clear all;
% 设置循环参数
start_month = 05;
end_month = 08;
start_year = 1974;
end_year = 1976;
% 存储温度指标的变量
avg_t_daily_new = [];
prev_num_time = 0;  % 记录前面的列数
 
% 循环读取和处理多个nc图像
for year = start_year:end_year     
    for month = start_month:end_month
            % 构建nc图像文件名
            file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc',year,month);
            % 读取温度数据
            t = ncread(file_name, 'TBOT');
            LONGXY = ncread(file_name, 'LONGXY');
            LATIXY = ncread(file_name, 'LATIXY');
            % 获取变量 t 的尺寸信息(依次为:经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time
            [num_lon, num_lat, num_time] = size(t);
            % 重塑矩阵为二维
            t_2d = reshape(t, [], num_time);
            % 拼接矩阵
            if num_time == prev_num_time  % 如果当前列数等于前面的列数,则不用再拼接
                avg_t_daily_new = [avg_t_daily_new, t_2d];
            else  % 否则拼接矩阵
                avg_t_daily_new = [avg_t_daily_new, zeros(size(avg_t_daily_new, 1), num_time - prev_num_time), t_2d];
            end
            prev_num_time = num_time;  % 记录当前列数
    end
end

发现代码中存在的问题:在每次循环时,都使用相同的变量名 file_name 来构建文件名,而没有根据当前的年份和月份来生成不同的文件名。因此,每次循环时实际上都读取的是同一个文件,导致结果重复记录。
解决思路,需要在每次循环时根据当前的年份和月份来动态生成文件名,可以使用以下代码来读取文件:

% 循环读取和处理多个nc图像  
for year = start_year:end_year       
    for month = start_month:end_month  
            % 构建nc图像文件名  
            file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc', year, month);  
            % 读取温度数据  
            t = ncread(file_name, 'TBOT');  
            LONGXY = ncread(file_name, 'LONGXY');  
            LATIXY = ncread(file_name, 'LATIXY');  
            % 获取变量 t 的尺寸信息(依次为:经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time  
            [num_lon, num_lat, num_time] = size(t);  
            % 重塑矩阵为二维  
            t_2d = reshape(t, [], num_time);  
            avg_t_daily_new{end+1} = t_2d;  
    end  
end
#在修改后的代码中,使用了动态生成文件名的方式,确保每次循环读取的是不同的文件。并且将 avg_t_daily_new 定义为动态增长的数组,确保每个文件的温度数据都能被正确地存储在其中。
#如有帮助,恭请采纳

问题可能出在循环的起始年份和月份没有正确设置。改为以下代码应该可以解决问题:

for year = start_year:end_year     
    for month = start_month:12
        % 构建nc图像文件名
        file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc',year,month);
        % 读取温度数据
        t = ncread(file_name, 'TBOT');
        LONGXY = ncread(file_name, 'LONGXY');
        LATIXY = ncread(file_name, 'LATIXY');
        % 获取变量 t 的尺寸信息(依次为经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time
        [num_lon, num_lat, num_time] = size(t);
        % 重塑矩阵为二维
        t_2d = reshape(t, [], num_time);
        avg_t_daily_new = [avg_t_daily_new, t_2d];
    end
    start_month = 1; %每进入一个新的年份,从1月开始读取
end

改动之处在于,每个年份的循环先从起始月份开始,直到12月,然后再进入下一个年份。同时,每进入一个新的年份,循环的起始月份也要重置为1月。这样可以保证每个年份的全部数据都被读取到。

光看代码好像没啥问题,可以私发文件帮你看看具体是啥原因

你的代码逻辑没有问题,问题可能出在数据的存储方式上。请确定你读取的图像文件是正确的,数据是按照正确的时间顺序排列的。另外,你可以在内嵌循环里加一些输出语句来检查每个文件名和其对应的时间是否正确。下面是一个简单的代码示例:
'''``




clc
clear all;
% 设置循环参数
start_month = 05;
end_month = 08;
start_year = 1974;
end_year = 1976;
% 存储温度指标的变量
avg_t_daily_new = [];

% 循环读取和处理多个nc图像
for year = start_year:end_year     
    for month = start_month:end_month
            % 构建nc图像文件名
            file_name = sprintf('F:\\TPHWL6Hrly\\clmforc.cruncep.V7.c2016.0.5d.TPQWL.%04d-%02d.nc',year,month);
            fprintf('正在读取文件:%s\n', file_name);
            % 读取温度数据
            t = ncread(file_name, 'TBOT');
            LONGXY = ncread(file_name, 'LONGXY');
            LATIXY = ncread(file_name, 'LATIXY');
            % 获取变量 t 的尺寸信息(依次为:经度、纬度、时间),并将其分别存储在自定义变量 num_lon、num_lat 和 num_time
            [num_lon, num_lat, num_time] = size(t);
            % 重塑矩阵为二维
            t_2d = reshape(t, [], num_time);
            avg_t_daily_new = [avg_t_daily_new, t_2d];
    end
end
'''end

```bash



这个代码会输出正在读取的文件名,你可以先运行一下看看是哪些文件读取出了问题。

感谢各位的解答。我检查了一下,发现是我的数据本身有问题。数据本身就是每一年的数据都是重复的。感谢PhoenixRiser的建议,我对数据进行了检查,发现了这个问题。