1

そして私の投稿に興味を示してくれてありがとう:)

使用しているデータについて簡単に説明します。

私はExcelからmatlabスクリプトへの重要なデータであるため、3つのベクトルになります。これらは:

  • "FIT_txt"(各セルに混合文字と数字を含む約25万行。繰り返し入力)
  • 「FIT_num」(数字のみを含む「FIT_txt」と同じ行数)
  • 「セクター」(各セルに混合文字と数字を含む約5,000行。一意のエントリ)

今、私が達成したいこと:

  1. 「sector」の各行が「FIT_txt」に表示される回数をカウントするベクトルを作成します。例:「sector」の最初のエントリが「AB10」である場合、「FIT_txt」で「AB10」が発生する回数をカウントするベクトルを作成します。これは、新しいベクトルの最初の行に保存する必要があります。新しいベクトルの2行目は、「FIT_txt」などの「sector」(たとえば「AB11」)からの行2の出現をカウントします。

  2. 「sector」エントリに対応する「FIT_txt」のエントリと同じ行にある「FIT_num」のすべての数値を追加するベクトルを作成し、それに応じて並べ替えます。例:「sector」の行1の「AB10」は「FIT_txt」で3回発生します-行2、500、2000で発生します。「FIT_num」の行2、500、2000を合計して、新しいベクトルの最初の行。

さて、これは私の問題を単純化したものです。基本的に、私はより多くのデータを使用しており、このプロセスを繰り返して、はるかに多くの新しいベクトル/行列を見つけています。単純化に関して、私はこれを行うことによって問題を解決することができました:

units = zeros(length(sector),1);
installed = zeros(length(sector),1);    

for a = 1:length(sector)
        for z = 1:length(FIT_txt(:,1))

            if strcmp((FIT_txt(z,1)),(sector(a)))==1

                units(a,1) = units(a,1) + 1;
                installed(a,1) = installed(a,1) + FIT_num(z,1);

            end

        end
    end

残念ながら、これは非常に非効率的で、計算に時間がかかりすぎるのではないかと心配しています。

私はこれを使用して、私の最初の質問(出現を数える)に対してまともな結果を達成することができました:

units = zeros(length(sector),1);

for a = 1:length(sector)
    units(a,1) = sum(strcmp((FIT_txt(:,1)),(sector(a)))
end

これは問題なく機能しますが(まだ少し時間がかかりますが)、2番目の質問(対応する「FIT_num」の値を数える)を解決する方法がわかりません。

私の問題を解決するのに可能な限り効率的な解決策を見つけるのを手伝っていただければ幸いです。

事前にどうもありがとうございました。

ジョン

4

1 に答える 1

1

これを段階的に解決してみましょう。はセル配列であり、はFIT_txtセルNx1配列であると想定しています。sectorMx1

sector(ii)まず、に表示されるFIT_txtの行と、その回数を確認します。

ii=1;
sector_occurrence = strfind(FIT_txt,sector(ii));

これによりN、FIT_txtの各行のセルが得られ、各セルには、sector(ii)が見つかった各行の実際の場所が含まれます。行ごとのカウントが必要なだけなので、numelを使用してそれを取得します。

cellfun(@numel,sector_occurrence );

sectorこれは、ループまたはarrayfunを使用してのすべての要素に対して実行できます。

sector_occurrence = cell2mat(arrayfun(@(ii) cellfun(@numel,strfind(FIT_txt,sector{ii})),1:numel(sector),'uni',false'));

これで、NxMマトリックスができました。行iと列jの要素は、で何回sector(j)発生するかを示しFIT_txt(i)ます。

*コメントを読んでいます...ああ、でもセクターが見つかった場合、FIT_txtはセクターとまったく同じです。これにより、strcmpとarrayfunを使用して上記のすべてを単純化できます。

sector_occurrence = cell2mat(arrayfun(@(sectorii) strcmp(FIT_txt,sectorii), sector', 'uni',false))



さて、総和に移りましょう。

これは、オカレンスベクトルと。のベクトル積であり、行列に:FIT_numを掛けることで、1回の呼び出しですべてを取得できます。sector_occurrenceFIT_num

sumresult = sector_occurrence'*FIT_num;

として定義されている'ため、転置演算子に注意してください。sector_occurrenceNxM

>> sector=[{'AB10'} ; {'b'}];
>> FIT_txt=[{'AB10'} ; {'a'} ; {'b'} ; {'ZX5b'} ; {'AB10'} ; {'b'}];
>> FIT_num = (1:6)';

>> sector_occurrence = strfind(FIT_txt,sector(ii))

sector_occurrence =

     1     0
     0     0
     0     1
     0     0
     1     0
     0     1

>> sumresult = sector_occurrence'*FIT_num

sumresult =

     6
     9

もちろん、それは完全に一致している必要があります(あなたが言ったように)は、と等しくなく、またb等しくないでしょう。Bbbb

大規模なデータセットに関する注意

sector_occurrencelogical配列なので、それほど多くのメモリは必要ありません。ただし、で乗算を実行するとFIT_num、に変換されfloatます。これには、8倍のスペースが必要です。最終結果は小さな(メモリ内の)ベクトルですが、中間プロセスによってPCが溶ける可能性があります。ループで乗算を行うことにより、これを回避できます。

sumresult=NaN(numel(sector),1); %preallocation is a good thing
for ii=1:numel(sector)
    sumresult(ii)=sector_occurrence(:,ii)'*FIT_num;
end
于 2012-08-01T13:46:50.113 に答える