首页 > 解决方案 > 从数据集中提取最小值的函数 [MATLAB]

问题描述

我已经制作了一个函数,可以从给定月份和年份的特定时间从数据集中提取所有温度。

看起来像: exctractperiod(data, year, month, time)

如前所述,这将一次提取特定月份的所有温度,例如 1400。

我现在想找到某个月份的最低温度,比如多年的一月。例如,如果我查看 1997 年到 2006 年之间的 1 月。现在我想要 1997 年到 2006 年之间 1 月的最低注册温度。

到目前为止我的进展是下面的代码:

function [algo] = getMiniserieone(data, startYear, endYear, time)

v = zeros(12,2); 

for month = 1:12
  for year  = startYear:1:endYear

     p = extractperiodtwo(data, year, month, time);

     q = min(p);

    v(month,1) = v(month,1) + q;
    v(month,2) = v(month,2) + 1;

    algo = v(12,2);
  end
end 
end

但是,我确实收到了错误消息:

    Unable to perform assignment because the size of the left side is 
   1-by-1 and the size of the right
    side is 0-by-1.

在命令窗口调用函数时:

>> getMiniserieone(data, 1996, 2006, 1400)


Error in getMiniserieone (line 12)
    v(month,1) = v(month,1) + q;

但我一直无法解决这个问题。

我对上述程序的意图是让我们假设 1996 年至 2006 年期间的特定时间提取 1 月至 12 月之间所有月份的最低温度。这意味着在 1996 年至 2006 年 1 月之间的某个时间,比如 1300 年,我想要当时那个月的最低温度。然后将其存储在我的向量v第 1 列中,第 2 列将表示月份。

我的问题是如何解决这个问题,我不确定错误消息是什么意思?这是否可能意味着 q 不是单个元素值?

我希望所提供的信息足以理解问题,如果不能随意询问。


根据要求,代码extractPeriod()

function [mdata] = extractperiodtwo(data, year, month, time)

x = year*100 +month;

k = find( floor(TEMPUF(:,1)/100) == x & (data(:,2)==time));

mdata = data(k,3);

end

标签: matlabfunction

解决方案


因此,您遇到了两个问题。第一种情况是您的extractperiodtwo()函数找不到值,它返回一个空向量。您可以在循环中写入一个检查,报告未找到给定条目的数据并处理错误。我推荐一个try-catch块(我在下面的代码中实现)。第二个问题与您如何存储每次迭代的最小值有关。

这是我的解决方案:

function [algo] = getMiniserieone(data, startYear, endYear, time)
  %initialize output
  algo = [zeros(12,1), (1:12)']; %col1 = min(temps), col2 = month
  % loop through months
  yearsToTest = startYear:1:endYear;

  for month = 1:12
    %initialize a year storage, i.e. on the first iteration
    % this will be january minimum temps from startYear:endYear, 
    % on iteration 2, it will be all february temps from startYear:endYear
    % and so on until it completes month == 12.
    lowTempsOverYears = nan(1,length(yearsToTest));

    for yearNum = 1:length(yearsToTest)
      %edit: forgot to paste this line, sorry.
      year = yearsToTest(yearNum);

      p = extractperiodtwo(data, year, month, time);

      q = min(p);

      try
        %try appending the min
        lowTempsOverYears(yearNum) = q;
      catch
        fprintf(2, ...
          '\nNo data found for month=%d, year=%d.\n  Skipping...\n', ...
          month, ...
          year);
      continue
      end
    end
    % inner loop is over, now we need the minimum of mins for the month
    algo(month, 1) = min(lowTempsOverYears,[],'omitnan');
  end

end

所以我所做的是添加了第二个向量,它在间隔内lowTempsOverYears跟踪min(p)每个月。startYear:endYear然后我得到最小值并将其存储在该月的相应行中,在输出变量中。我使用 初始化lowTempsOverYearsnan()因为它允许我稍后将min()标志'omitnan'设置为 true,有效地忽略出现在向量中的任何 nan。

或者

您可以在矩阵中捕获多年来和几个月的所有临时数据,然后执行您选择的统计数据。例如,您的函数内部可能是:

function algo = getMiniserieone(data, startYear, endYear, time)
    algo = [zeros(12,1), (1:12)'];
    yearsToTest = startYear:1:endYear;
    % create local storage of values as matrix
    v = nan(12,length(yearsToTest));
    %loop
    for month = 1:12
      for yearNum = 1:length(yearsToTest)
        % current year to gather data from
        year = yearsToTest(yearNum);
        % p could be scalar, vector, empty
        p = extractperiodtwo(data, year, month, time);
        % q is scalar or empty
        q = min(p);
        try
          %try inserting the min temp
          v(month,yearNum) = q;
        catch
          fprintf(2,'\nNo data at month=%d, year=%d.\n  Skipping...\n', ...
            month, year ...
            );
        continue
        end
      end
    end
    % now all data is stored in a matrix perform statistic
    algo(:,1) = min(v, [], 2, 'omitnan');
end

推荐阅读