0

次の例を検討してください。

Jday = datenum('2007-01-01 00:00','yyyy-mm-dd HH:MM'):1:...
    datenum('2009-12-31 23:00','yyyy-mm-dd HH:MM');
Jday2 = datenum('2008-01-01 00:00','yyyy-mm-dd HH:MM'):1:...
    datenum('2010-12-31 23:00','yyyy-mm-dd HH:MM');

Data{1} = [Jday;1+(length(Jday)-1).*rand(1,length(Jday))]';
Data{2} = [Jday2;1+(length(Jday)-1).*rand(1,length(Jday))]';
Data{3} = [Jday;1+(length(Jday)-1).*rand(1,length(Jday))]';

for i = 1:length(Data);
    d_nan{i} = floor(1+(length(Jday)-1).*rand(1,100));
end

for i = 1:length(Data);
    a(i) = length(d_nan{i});
    for ii = 1:a(i);
        Data{i}(d_nan{i}(ii),2) = nan;
    end
end

この例では、3 つのセル配列を含むセル配列 'Data' があります。各セル配列の最初の列には、2 番目の列の値のユリウス日が含まれています。各セル配列には多数の nan 値があります。各セル配列の nan 値を、その特定のユリウス日の他のセルの値の平均に置き換えたいと思います。3 つのセルが同時にデータを表示しないため、私の問題は複雑です (ただし、Data{1} と Data{3} は同じ日です)。3 つのセル間でユリウス日が同一である場合、この問題は以下を使用して解決できます。 isnan を使用して nan の位置を見つけ、それらの行を (他のセルの) 他の行の nanmean で置き換えます。

誰かがこの問題に取り組む効果的な方法を提案できますか? お時間をいただきありがとうございます

4

3 に答える 3

1

考えられる解決策は次のとおりです。

  1. すべてのデータを連結してNaN値を見つける:

    D = [vertcat(Data{:})];
    nanidx = find(isnan(D(:, 2)));
    
  2. 連結されたマトリックス内のそのkような値のインデックスごとに、同じ日付の他のエントリを見つけます。NaND

    entries = find(D(:, 1) == D(k, 1));
    
  3. NaNこれらのエントリから非値をフィルタリングし、元NaNの位置kを平均値に置き換えます。

    values = D(~isnan(D(entries, 2)) & ~ismember(entries, nanidx), 2);
    D(k, 2) = mean(values);
    
  4. すべてを cell 配列に戻す:

    Data = mat2cell(D, cellfun('length', Data), 2)';
    

コピー&ペーストしやすい最終的なコードは次のとおりです。

D = [vertcat(Data{:})];
nanidx = find(isnan(D(:, 2)));
for k = transpose(nanidx(:))
    entries = find(D(:, 1) == D(k, 1));
    values = D(~isnan(D(entries, 2)) & ~ismember(entries, nanidx), 2);
    D(k, 2) = mean(values);
end
Data = mat2cell(D, cellfun('length', Data), 2)';
于 2013-01-29T16:37:26.947 に答える
0

これはあなたの問題を解決するかもしれませんが、それはまさにあなたが求めたものではありません. 各 NaN 値で、補間から NaN を取り除いた、その日に補間された値の平均に置き換えます。

for i = 1:3
    for j = 1:length(Jday)
        if isnan(Data{i}(j,2))
            d = Data{i}(j,1);
            Data{i}(j,2) = mean([ ...
                interp1(Data{1}(find(~isnan(Data{1}(:,2))),1),Data{1}(find(~isnan(Data{1}(:,2))),2),d) ...
                interp1(Data{2}(find(~isnan(Data{2}(:,2))),1),Data{2}(find(~isnan(Data{2}(:,2))),2),d) ...
                interp1(Data{3}(find(~isnan(Data{3}(:,2))),1),Data{3}(find(~isnan(Data{3}(:,2))),2),d)]);
        end
    end
end
于 2013-01-29T16:15:57.213 に答える
0

編集を見たかどうかわからない(私は新しいユーザーなので、これがどのように機能するかをまだ学んでいます)ので、ここにあなたが求めていることを行い、他の2つが同じ日付を持たないNaNを残すソリューションがあります.

for i = 1:3
    for j = 1:length(Jday)
        if isnan(Data{i}(j,2))
            d = Data{i}(j,1);
            if (~isempty(find(Data{:,1}==d,1)) && ...
                ~isempty(find(Data{:,2}==d,1)) && ...
                ~isempty(find(Data{:,3}==d,1)))
                Data{i}(j,2) = nanmean([ ...
                    Data{1}(find(Data{:,1}==d,1),2) ...
                    Data{2}(find(Data{:,2}==d,1),2) ...
                    Data{3}(find(Data{:,3}==d,1),2) ]);
            end
        end
    end
end
于 2013-01-30T04:56:13.523 に答える