Удаление строк из ячейки с учетом определенного условия

#matlab #cell #conditional-statements

#matlab #ячейка #условные операторы

Вопрос:

У меня есть большая переменная типа ячейки, отсортированная по FIRM (A(:,2)), и я хочу стереть все строки, в которых одна и та же фирма не появляется как минимум 3 раза подряд. В этом примере:

          FIRM 

 1997   'ABDR'  0,56    464 1641    19970224
 1997   'ABDR'  0,65    229 9208    19970424
 1997   'ABDR'  0,55    125 31867   19970218
 1997   'ABD'   0,06    435 8077    19970311
 1997   'ABD'   0,00    150 44994   19970804
1997    'ABFI'  2,07    154 46532   19971209
 

Я бы оставил только:

 1997    'ABDR'  0,56    464 1641    19970224
1997    'ABDR'  0,65    229 9208    19970424
1997    'ABDR'  0,55    125 31867   19970218
 

Большое спасибо.

Примечания:

Я использовал fopen и textscan для импорта файла csv. Я выполнил некоторые изменения в некоторых переменных, чтобы все они помещались в переменную типа ячейки

Я преобразовал некоторые числовые элементы в укусы

 F_x=num2cell(Data{:,x});
 

Я получил новую переменную только с year

 F_ya=max(0,fix(log10(F_y) 1)-4);
F_yb=fix(F_y./10.^F_ya);
F_yc = num2cell(F_yb);
 

Создайте новую ячейку с нужными мне переменными

 A=[F_5C Data{:,1} Data{:,2} Data{:,3} Data{:,4} F_xa F_xb];
 

Это означает, что внутри ячейки у меня есть некоторые переменные, которые являются строками, а другие — числами.

Ответ №1:

Я собираюсь предположить, что ваши имена хранятся в cell массиве. Таким образом, ваши имена на самом деле будут:

 names = {'ABDR', 'ABDR', 'ABDR', 'ABD', 'ABD', 'ABFI'};
 

Затем мы можем использовать strcmpi . Что делает эта функция, так это то, что она сравнивает две строки вместе. Он возвращает true , если строки совпадают и false в противном случае. Это также не зависит от регистра, поэтому ABDR будет таким же, как abdr .

Вы бы назвали strcmpi так:

 v = strcmpi(str1, str2);
 

Альтернативно str2 может быть массив ячеек. Как это будет работать, так это то, что потребуется одна строка str1 и сравнение с каждой строкой в каждой ячейке массива ячеек. Затем он вернет логический вектор того же размера, str2 который указывает, есть ли у нас совпадение в этом конкретном местоположении или нет.

Таким образом, мы можем просмотреть каждый элемент names и посмотреть, сколько совпадений у нас есть в целом со всем names массивом ячеек. Затем мы можем выяснить, какие местоположения нам нужно выбрать, проверив, есть ли у нас по крайней мере 3 совпадения или более для каждого имени в names массиве. Другими словами, мы просто суммируем логический вектор для каждой строки внутри names и фильтруем те, которые суммируют до 3 или более. Мы можем использовать cellfun , чтобы помочь нам выполнить это. Как таковой:

 sums = cellfun(@(x) sum(strcmpi(x,names)), names);
 

Таким образом, это дает:

 sums =

 3     3     3     2     2     1
 

Теперь нам нужны те местоположения, в которых их три или более. Как таковой:

 locations = sums >= 3

locations =

 1     1     1     0     0     0
 

Таким образом, это строки, которые вы можете использовать для фильтрации вашей матрицы. Это также логический вектор. Предполагая, что A это содержит ваши данные, вы просто A(locations,:) должны отфильтровать все те строки, которые встречаются три или более раз для определенного имени. Я действительно не знаю, как вы построили A , поэтому я предполагаю, что это похоже на 2D-матрицу. Если вы введете код, который вы использовали для построения этой матрицы, я изменю свой пост, чтобы заставить его работать на вас. В любом случае важно то, что locations . Здесь указано, какие строки вам нужно выбрать, чтобы они соответствовали вашим критериям.

Комментарии:

1. Большое вам спасибо, этот код действительно хорошо объяснен, что я очень ценю, потому что я узнаю больше. Мои «имена» хранятся в виде cell массивов да! В данный момент я применяю его (я дам вам знать, сработало ли это), но я попытаюсь отредактировать свой вопрос, чтобы узнать, поможет ли просмотр кода! Спасибо!

2. @user3557054 — Хорошо, похоже, что ваши имена хранятся в Data{:,2} . То, что я только что написал, все равно должно работать. names в этом случае было бы просто Data{:,2} . Затем вы должны взять locations и подмножить свою матрицу A , чтобы выбрать только те строки, о которых мы говорили. Судя по тому, как вы построили A , это должно сработать

3. ОК. Я пробую это прямо сейчас, я тоже думаю, что это сработает. Я все равно дам вам знать в конце! Спасибо

4. @user3557054 — Надеюсь, это сработало !… видя, как вы приняли мой ответ :). Потрясающе. Удачи!

5. Да, это сработало! Я все еще хотел проверить еще раз сегодня, но это работает! Спасибо! 🙂