2

テスト中に記録されたデータを手動で Matlab にインポートするためのスクリプトを作成しました。

各テストの実行では、約 2600 の変数が.csvファイルに保存されます。それぞれのファイルには、2 つのヘッダー行、2 つのデータ列、および;区切り記号があります。

ファイル名は、監視プログラムによって使用される内部 C 構造体に由来するため、このようなものです。foo.bar.another.foo.bar.local_varname#VALUE.csvこれを使用して、Matlab で構造体を再作成し、それのみをtest_name.matファイルに保存したいと考えています。

多くの場合、local_varname長さは 63 文字を超えます。そのため、Matlab が名前を切り捨てずに名前を短縮するためのいくつかの置換規則があります (したがって、名前の競合を回避しようとします)。

これがコードです

clear all
clc

% Main names
path_self         = pwd;
backslash_indices = strfind(path_self,'\');
test_name         = path_self(backslash_indices(end)+1:end); % the directory name gives me the test_name

% Preallocation
filenames = cell(1,2600);
addresses = cell(1,2600);
i=0;

% Full list
MyFiles = dir(path_self); 

% Discard subdirectories and non interesting files
for k=1:length(MyFiles)
    if ~MyFiles(k).isdir,
        if ~isempty(strfind(MyFiles(k).name,'#VALUE.csv'))
            i=i+1;
            % Too many files
            if i > length(filenames)
                filenames = [filenames cell(1,100)];
                addresses = [addresses cell(1,100)];
            end
            % Naming Substitution Rules

            %%% INSERT HERE BUNCH OF RULES

            % Addresses and names
            filenames{i} = strrep(filename,'#VALUE.csv','');
            addresses{i} = fullfile(path_self, MyFiles(k).name);
        end
    end
end
filenames = filenames(1:i);
addresses = addresses(1:i);

% Check that no conflicts are created
if length(filenames) ~= length(unique(filenames))
    error('filenames not unique')
end

% Housekeeping #1
clear MyFiles backslash_indices i k path_self

% Import data
for j=1:length(filenames)
    % Read data
    Data = importdata(addresses{j}, ';', 2);
    % Assign data
    eval([filenames{j}, '.time   = Data.data(:,1)./1000000;']); % Converted in seconds
    eval([filenames{j}, '.values = Data.data(:,2);']);
    % Let's avoid data corruption
    clear Data
end

% Housekeeping #2
clear filenames addresses j 

% Save data struct
save(test_name, '-regexp', '^((?!name).)*$')

今私の質問 情報を調査し、上記のコードを書くのを手伝っている間、私はしばしば人々がの使用に眉をひそめているのを見つけましたeval():なぜそうなのですか? 上記の場合、回避できますか?

ありがとう

EDIT @wakjahが示唆したように、containers.Map()アプローチをテストしました。残念ながら、その時点ではキーのリストが必要であり、データへのアクセスは正確ではないため、私たちのニーズには適していません (少なくとも同じ数のキーを意味する約 2600 の変数があることを思い出してください)。

@Dennis Jaheruddin が尋ねたことに関しては、データ構造体は使用可能であり、これらの長い varnames を使用しても、いかなる種類の競合も作成しません (2 つの連続する間の各 name* の.長さが 63 文字未満である場合)

*より適切な専門用語を使用していないことをお詫びします

4

3 に答える 3

4

Mathworks のこのページから:

eval 関数は非常に強力で柔軟性がありますが、プログラミングの問題に対する最善の解決策とは限りません。eval を呼び出すコードは、多くの場合、他の関数や言語構造を使用するコードよりも効率が悪く、読み取りやデバッグが困難です。...

括弧表記を使用して、タスクを簡単に実行できます。簡単な例:

s = struct();
myFieldName = 'test';
s.(myFieldName) = myFieldValue;

これによりtest、構造体のフィールドが に設定さsmyFieldValueます。

このテーマに関する Loren のブログ投稿もあります。

編集:フィールド名が63文字を超えることが要件であるため、別の方法はcontainers.Mapオブジェクトを使用することです。以下に少し例を示します。

>> m = containers.Map();
>> myFieldName = repmat('abcdefg', [1 10]); % 70 chars long
>> m(myFieldName) = 12345; 
>> m(myFieldName)

ans =

       12345
于 2013-03-28T12:34:02.257 に答える
3

あなたがやろうとしていることを見た後、私の最初の考えは、あなたは奇妙なことをしているということです.

変数名が 63 文字を超えると、基本的に問題が発生します。代わりに、次の簡単な解決策をお勧めします。

2 つのフィールドを持つ構造体を使用します。

  • ファイル名
  • 価値

このようにして、データはより自然に構造化され、すべてのファイルに対して 1 つの変数のみが必要になります。


value は構造体または配列にすることができ、単一の文字列または数値に限定されないことに注意してください。

ここで考えられる唯一の本当の欠点は、オートコンプリートは変数名では機能するが、その内容では機能しないということですが、それはわずかな代償であるはずです。

于 2013-03-28T13:26:53.280 に答える
0

genvarnameから有効な一意の変数名を生成する関数を使用することを検討しましたlocal_varnameか?

于 2013-03-28T12:59:55.833 に答える