WedX - журнал о программировании и компьютерных науках

Фильтрация вектора по условию

Я пытаюсь отфильтровать вектор целых чисел.
Мое условие состоит в том, что расстояние между двумя последовательными элементами должно быть не менее 100 ; если нет, удалите элемент и посмотрите на следующего кандидата.
Вот пример:

set.seed(42)
input <- sort(sample(1:1000, 20))
head(input, 20)


[1] 24  49  74 128 146 153 165 228 303 321 356 410 532 561 601 622 634 839 882 997

Если я начну с первого элемента 24, я хотел бы сохранить первый элемент, который находится на расстоянии не менее 100 от него.
В этом случае это будет 128.

Затем, начиная с 128, повторите тот же процесс.
Результат должен быть:

24 128 228 356 532 634 839 997

Мне удалось создать быстрый и грязный цикл, который дает правильный результат, но я могу предположить, что это будет не очень эффективно для очень больших векторов...

result <- integer(length(input))
result[1] <- input[1]
for(i in seq_along(input)[-1]) {
  if(is.na(input[2])) break

  if(input[2] - input[1] < 100) {
    input <- input[-2]
  } else {
    result[i] <- input[2]
    input <- input[-1]
  }
}

result <- result[result != 0]

Что было бы эффективным способом получить ожидаемый результат? Можно ли это сделать с помощью векторизации?

07.06.2019


Ответы:


1

Тщательно не проверено, но я считаю, что это приведет вас туда. Я использую purrr::accumulate. Это довольно изящная проблема :-) в надежде увидеть какие-то другие решения/подходы, так что, возможно, оставьте это открытым (без ответа) на некоторое время...

library(purrr)

input <- c(24, 49, 74, 128, 146, 153, 165, 228, 303, 321, 356, 410, 532, 561, 601, 622, 634, 839, 882, 997)
idx <- which(accumulate(diff(input), ~ ifelse(.x >= 100, .y, .x + .y)) >= 100)
input[c(1, idx + 1)]
#> [1]  24 128 228 356 532 634 839 997

И чтобы это читалось немного больше purrr, я полагаю, мы могли бы сделать:

accumulate(diff(input), ~ if_else(.x >= 100, .y, .x + .y)) %>%
  map_lgl(~ . >= 100) %>%
  which %>%
  { input[c(1, . + 1)] }
07.06.2019

2
  • Друзья не позволяют друзьям использовать ifelse() для скалярных сравнений или T для TRUE: unique(Reduce(function(x, y) if (y - x >= 100) y else x, input, accumulate = TRUE)) 08.06.2019
  • @MartinMorgan Я согласен. Спасибо 08.06.2019
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]