Matlab cellfun, как применить индексацию к строкам для каждого элемента?

У меня возникли проблемы с индексацией строк, содержащихся в массиве ячеек, с помощью функции cellfun. У меня есть массив ячеек со строками различного содержания, и я пытаюсь извлечь числа между словами «вход» и «дБм» в следующем примере, где в интересующих строках всегда есть слово «внимание». (Мое фактическое использование состоит из десятков строк, но это упрощенный пример). Я могу получить индексы ячеек, содержащих «atten», используя функцию «contains», которая работает как положено. Я также могу получить индексы в каждой ячейке, которые хочу извлечь, с помощью функции «strfind» внутри cellfun, которые показаны ниже как переменные «st» и «sp».
Но я не могу использовать значения «st» и «sp» для извлечения интересующих чисел, а именно -70,6, -67,5 и -69,9 в этом примере. Возможен ли этот тип индексации с помощью cellfun? Или мне просто использовать цикл for? Код с комментариями внизу показывает значения, которые я сейчас получаю в out_cell_array, и что мне нужно получить.

d = {'some random text';...
    'atten 16.0 input -70.6 dBm';...
    'atten 0.0 input -67.5 dBm';...
    'atten 13.0 input -69.9 dBm';...
    'some other random text'};

idx = find(contains(d,'atten'));
st = cellfun(@(x) strfind(x, 'input'), d(idx)) + 6;     % index starting 6 to the right "input"
sp = cellfun(@(x) strfind(x, 'dBm'), d(idx)) - 2;       % index starting 2 to the left of "dBm"     
out_cell_array = cellfun(@(x){x(st:sp)}, d(idx));

%values after running above. everything works until the last "cellfun" line, which isn't indexing how I want
% disp(idx')            2 3 4
% disp(d(idx)')         'atten 16.0 input -70.6 dBm'  'atten 0.0 input -67.5 dBm'  'atten 16.0 input -69.9 dBm'
% disp(st')             18 17 18
% disp(sp')             22 21 22
% disp(out_cell_array') '-70.6' '67.5 ' '-69.9'  <-- is not indexing using the values of st and sp

%%%% I want this:
% out_cell_array = {d{2}(18:22); d{3}(17:21); d{4}(18:22)};
% disp(out_cell_array')  '-70.6' '-67.5' '-69.9'

Всегда сначала следует писать простой цикл, если только векторизация не является тривиальной и очевидной. Если затем окажется, что он работает слишком медленно (узкое место в вашем коде), вы можете начать думать о том, чтобы приложить усилия к векторизации. В современных версиях MATLAB векторизованный код часто ненамного быстрее, чем код цикла, а иногда и намного медленнее (когда требуются очень большие промежуточные массивы), поэтому часто не стоит прилагать усилия к векторизации.

Cris Luengo 22.04.2024 22:14

Хорошо, это нормально. Я буду использовать цикл for. Спасибо.

Sanjo 22.04.2024 23:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Значения x, st и sp в вашем последнем файле CellFun не совпадают. Попробуй это:

x = d(idx); % extract the appropriate cells first
arrayfun(@(k)x{k}(st(k):sp(k)),(1:numel(st))','uni',false') % then extract the strings

Или, если вы действительно хотите использовать CellFun,

cellfun(@(x,st,sp){x(st:sp)}, d(idx),num2cell(st),num2cell(sp))

Спасибо. Я не смог использовать другое предложение со «совпадениями», потому что я использую более старую версию Matlab, так что это мой победитель :)

Sanjo 29.04.2024 16:43

Вы можете использовать строковые функции match вместе с некоторыми шаблонами , а также ExtractBetween, чтобы сделать это довольно просто:

% Find all elements that start with "atten", and have "input" and "dBm"
ismatch = matches(d, "atten" + wildcardPattern + "input" + wildcardPattern + "dBm");
% Pick out whatever is between "input" and "dBm" and convert it to double.
str2double(extractBetween(d(ismatch), "input", "dBm"))

Спасибо. Я мог бы использовать функцию совпадений, потому что моя версия Matlab использует какой-то метод Java. Но я буду иметь это в виду, если моя компания когда-нибудь обновит нашу лицензию :) >> совпадение — это метод Java % java.lang.String метод

Sanjo 29.04.2024 16:44

Это позор. Я думаю, что возможности обработки текста в последних версиях MATLAB значительно упрощают жизнь.

Edric 30.04.2024 10:19

Другие вопросы по теме