matlab - xlabel - Использование find со структурой



plot names matlab (2)

Еще один ответ на этот вопрос! На этот раз мы сравним производительность следующих 4 методов:

  1. Мой оригинальный метод
  2. Первоначальный метод EitanT (который не обрабатывает emtpies)
  3. Улучшенный метод EitanT с использованием строк
  4. Новый метод: простой для цикла
  5. Еще один новый метод: векторизованная, надежная версия

Тестовый код:

% Set up test
N = 1e5;

S(N).b = [];
for ii = 1:N
    S(ii).b = randi(6); end

% Rody Oldenhuis 1
tic
sol1 = find( cellfun(@(x)isequal(x,6),{S.b}) );
toc

% EitanT 1
tic
sol2 = find([S.b] == 6);
toc

% EitanT 2
tic
str = sprintf('%f,', S.b);
values = textscan(str, '%f', 'delimiter', ',', 'EmptyValue', NaN);
sol3 = find(values{:} == 6);
toc


% Rody Oldenhuis 2
tic
ids = false(N,1);
for ii = 1:N
    ids(ii) = isequal(S(ii).b, 6);
end
sol4 = find(ids);
toc

% Rody Oldenhuis 3
tic
idx = false(size(S));
SS = {S.b};
inds = ~cellfun('isempty', SS);
idx(inds) = [SS{inds}]==6;
sol5 = find(idx);
toc

% make sure they are all equal
all(sol1(:)==sol2(:))
all(sol1(:)==sol3(:))
all(sol1(:)==sol4(:))
all(sol1(:)==sol5(:))

Результаты на моей машине на работе (AMD A6-3650 APU (4 ядра), 4 ГБ оперативной памяти, Windows 7 64 бит):

Elapsed time is 28.990076 seconds. % Rody Oldenhuis 1 (cellfun)
Elapsed time is 0.119165 seconds.  % EitanT 1 (no empties)
Elapsed time is 22.430720 seconds. % EitanT 2 (string manipulation)
Elapsed time is 0.706631 seconds.  % Rody Oldenhuis 2 (loop)
Elapsed time is 0.207165 seconds.  % Rody Oldenhuis 3 (vectorized)

ans =
     1
ans =
     1
ans =
     1
ans =
     1

На моем Homebox (AMD Phenom (tm) II X6 1100T (6 ядер), 16 ГБ оперативной памяти, Ubuntu64 12.10):

Elapsed time is 0.572098 seconds.  % cellfun
Elapsed time is 0.119557 seconds.  % no emtpties
Elapsed time is 0.220903 seconds.  % string manipulation
Elapsed time is 0.107345 seconds.  % loop
Elapsed time is 0.180842 seconds.  % cellfun-with-string

Должен любить этот JIT :)

и ничего себе ... кто-нибудь знает, почему две системы ведут себя так по-другому?

Кроме того, малоизвестный факт - cellfun с одним из возможных строковых аргументов невероятно быстр (что показывает, сколько анонимных аномальных функций требуется ...).

Тем не менее, если вы можете быть абсолютно уверены, что нет пустых тарелок, пойдите для первоначального ответа EitanT; для этого и предназначен Matlab. Если вы не можете быть уверены, просто займитесь циклом.

https://src-bin.com

У меня есть структура, содержащая тысячи образцов данных. Каждая точка данных содержит несколько объектов. Например:

Structure(1).a = 7
Structure(1).b = 3
Structure(2).a = 2
Structure(2).b = 6
Structure(3).a = 1
Structure(3).b = 6
...
... (thousands more)
...
Structure(2345).a = 4
Structure(2345).b = 9

... и так далее.

Если бы я хотел найти индексный номер всех объектов .b ', содержащих число 6, я бы ожидал, что следующая функция выполнит трюк:

find(Structure.b == 6)

... и я ожидаю, что ответ будет содержать «2» и «3» (для ввода, показанного выше).

Однако это не работает. Каков правильный синтаксис и / или я мог бы упорядочить мои данные более логичным образом в первую очередь?


Answer #1

Основываясь на ответе EitanT на комментарий Джонаса, более безопасным способом может быть

>> S(1).a = 7;
   S(1).b = 3;
   S(2).a = 2;
   S(2).b = 6;
   S(3).a = 1;
   S(3).b = [];
   S(4).a = 1;
   S(4).b = 6;

>> find( cellfun(@(x)isequal(x,6),{S.b}) )
ans =
     2     4

Это, вероятно, не очень быстро, хотя (по сравнению с версией EitanT), поэтому используйте только при необходимости.





find