Подсчет строк с идентичными и диапазонными значениями, включая расширение диапазона.

Вопрос или проблема

У меня есть данные в следующем формате, где в первой строке нижние и верхние значения одинаковы, а в следующей строке нижние и верхние значения образуют диапазон (т.е. от 73760 до 73796). Мне нужно подсчитать количество всех строк, где нижние и верхние значения одинаковы, и, с другой стороны, количество всех строк, где нижние и верхние значения образуют диапазон, а также расширенное количество диапазонных данных (т.е. количество значений в диапазоне).

Вывод будет следующим:

индивидуальные данные : 1
диапазонные данные : 1
расширенный диапазон : 37 (расширение от 73760 до 73796)

Входные данные выглядят следующим образом:

TMI=012813 FCI=00 low=000654 up=000654 sor=0E
TMI=012813 FCI=00 low=073760 up=073796 sor=0E

С помощью perl:

perl -lne '
  if (/ low=(\d+) up=(\d+) /) {
    $range = $2 - $1 + 1;
    $count[$range == 1]++;
    $max_range = $range if $range > $max_range;
  }
  END {
    printf "индивидуальные данные: %d\nдиапазонные данные: %d\nрасширенный диапазон: %d\n",
      $count[1], $count[0], $max_range;
  }' < ваш-файл

Или если расширенный диапазон подразумевает общий диапазон всех значений для недискретных значений, в отличие от максимальной длины диапазона для любой одной строки:

perl -lne '
  if (/ low=(\d+) up=(\d+) /) {
    $count[$2 == $1]++;
    unless ($1 == $2) {
      $min_low = $1 if $1 < $min_low;
      $max_up = $2 if $2 > $max_up;
    }
  }
  END {
    printf "индивидуальные данные: %d\nдиапазонные данные: %d\nрасширенный диапазон: %d\n",
      $count[1], $count[0], $max_up - $min_low + 1;
  }' < ваш-файл

С помощью Miller (mlr):

$ mlr --ifs space put -q -f script file
Расширенный диапазон: 37 (73760 до 73796)
Единственные данные: 1
Диапазонные данные: 1

Входные данные выглядят очень похоже на DKVP (“разделенные пары ключ-значение”), родной формат данных Miller, но используют пробелы вместо запятых для разделителей полей, поэтому мы используем --ifs space в командной строке mlr для установки разделителя входных полей.

Скрипт в script был вдохновлен ответом Stéphane, но интерпретирует вопрос так, как будто вы хотите видеть расширенный диапазон для всех диапазонов длиной больше 1.

lo = int($low, 10);
hi = int($up, 10);
range = 1 + hi - lo;

@count[int(range == 1)] += 1;

if (range > 1) {
    print "Расширенный диапазон: " . range . " (" . lo . " до " . hi  . ")";
}

end {
    print "Единственные данные: " . @count[1];
    print "Диапазонные данные: " . @count[0];
}

Ответ или решение

Чтобы решить задачу подсчета строк с идентичными и диапазонными значениями, включая расширение диапазона, нужно внимательно рассмотреть данные, которые вы предоставили. Мы будем разбираться с теми строками, в которых значения "low" и "up" меняются, что позволяет нам делить данные на две категории: отдельные значения и диапазоны.

Анализ задачи

Дан набор строк, каждая из которых содержит параметры, включая "low" и "up". Задача состоит в следующем:

  1. Посчитать количество строк, где значения "low" и "up" одинаковые (индивидуальные данные).
  2. Посчитать количество строк, где значения "low" и "up" образуют диапазон (диапазонные данные).
  3. Рассчитать расширенный диапазон для всех диапазонных значений, то есть количество значений в диапазоне.

Примеры данных

Входные данные выглядят следующим образом:

TMI=012813 FCI=00 low=000654 up=000654 sor=0E
TMI=012813 FCI=00 low=073760 up=073796 sor=0E
  • Первая строка содержит одинаковые значения (low = up = 654).
  • Вторая строка представляет диапазон (от 73760 до 73796).

Ожидаемый вывод

В соответствии с вашими требованиями, вывод должен быть следующим:

individual data: 1
range data: 1
range expanded: 37 (expansion of 73760 to 73796)

Реализация на Perl

Мы можем использовать Perl для подсчета и расширения диапазонов.

perl -lne '
  if (/ low=(\d+) up=(\d+) /) {
    $low = $1;
    $up = $2;
    $range = $up - $low + 1;

    $count[$range == 1]++;
    $max_range = $range if $range > $max_range;

    if ($range > 1) {
      $expanded_count += $range;
      $min_low = $low if !defined $min_low || $low < $min_low;
      $max_up = $up if !defined $max_up || $up > $max_up;
    }
  }
  END {
    printf "individual data: %d\nrange data: %d\nrange expanded: %d (expansion of %d to %d)\n",
      $count[1], $count[0], $max_range, $min_low, $max_up;
  }' < your-file

Реализация на Miller (mlr)

Если вы предпочитаете использовать Miller, это возможно тоже:

$ mlr --ifs space put -q -f script file

Где script будет следующим:

lo = int($low, 10);
hi = int($up, 10);
range = 1 + hi - lo;

@count[int(range == 1)] += 1;

if (range > 1) {
    print "Range expanded: " . range . " (" . lo . " to " . hi  . ")";
}

end {
    print "Single data: " . @count[1];
    print "Ranged data: " . @count[0];
}

Заключение

Эти подходы, как на Perl, так и на Miller, предоставляют эффективный способ обработки данных с целью подсчета уникальных и диапазонных значений. Простота и мощь этих утилит позволяет быстро адаптироваться к меняющимся требованиям и объемам данных, что делает их незаменимыми инструментами для IT-специалистов.

Оптимизация SEO

Не забывайте, что такие статьи могут также включать ключевые слова, такие как "подсчет строк", "обработка данных на Perl", "анализ диапазонов", "машинное обучение и данные", что повысит видимость статьи в поисковых системах.

Оцените материал
Добавить комментарий

Капча загружается...