Средние строки с одинаковым первым столбцом

Для файла с двумя столбцами:

Id ht 510 69 510 67 510 65 510 62 510 59 601 29 601 26 601 21 601 20 

Мне нужен способ объединить все строки с одинаковым идентификатором в один, который имеет среднюю высоту. В этом случае (69 + 67 + 65 + 62 + 59) / 5 = 64 и (29 + 26 + 21 + 20) / 4 = 24, поэтому выход должен быть:

 Id Avg.ht 510 64 601 24 

Как я могу это сделать с помощью sed / awk / perl?

4 Solutions collect form web for “Средние строки с одинаковым первым столбцом”

Использование awk:

Входной файл

 $ cat FILE Id ht 510 69 510 67 510 65 510 62 510 59 601 29 601 26 601 21 601 20 

Awk в оболочке:

 $ awk ' NR>1{ arr[$1] += $2 count[$1] += 1 } END{ for (a in arr) { print "id avg " a " = " arr[a] / count[a] } } ' FILE 

Или с Perl в оболочке:

 $ perl -lane ' END { foreach my $key (keys(%hash)) { print "id avg $key = " . $hash{$key} / $count{$key}; } } if ($. > 1) { $hash{$F[0]} += $F[1]; $count{$F[0]} += 1; } ' FILE 

Выход:

 id avg 601 = 24 id avg 510 = 64.4 

И последнее для шутки, Perl темно-обфускации однострочный =)

 perl -lane'END{for(keys(%h)){print"$_:".$h{$_}/$c{$_}}}($.>1)&&do{$h{$F[0]}+=$F[1];$c{$F[0]}++}' FILE 
 #!/usr/bin/perl use strict; use warnings; my %sum_so_far; my %count_so_far; while ( <> ) { # Skip lines that don't start with a digit next if m/^[^\d]/; # Accumulate the sum and the count my @line = split(); $sum_so_far{$line[0]} += $line[1]; $count_so_far{$line[0]} += 1; } # Dump the output print "Id Avg.ht\n"; foreach my $id ( keys %count_so_far ) { my $avg = $sum_so_far{$id}/$count_so_far{$id}; print " $id $avg\n"; } 

Вывод:

 ire@localhost$ perl make_average.pl input.txt Id Avg.ht 510 64.4 601 24 

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

Кроме того, у вас есть буква l в одной из ваших колонок, маскировка под номером 1

Взгляните на то, что делается здесь: http://www.sugihartono.com/programming/group-by-count-and-sorting-using-perl-script/

Существенной трудной частью является операция «группа за». Связанный скрипт делает это с использованием хэша.

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

С gnu datamash :

 datamash -H -s -g 1 mean 2 <file 
  GroupBy (Id) означает ()
 510 64,4
 601 24 

Это указывает и g roups на 1 -ое поле, вычисляя mean значение 2 поля, сохраняя H eaders. Предполагается, что поля разделяются одной вкладкой. Используйте -W, --whitespace если они разделены несколькими пробелами или -t, --field-separator= для определения другого разделителя полей (пробел, запятая и т. Д.). Поскольку datamash требует отсортированного ввода, вывод будет отсортирован по сгруппированному столбцу.

  • Как преобразовать файл субтитров .txt в формат .srt?
  • Как передать путь к файлу через вызов perl из bash?
  • Некоторые ошибки возникли, когда я установил lucene, модуль perl!
  • Perl печатает строки, соответствующие столбцам файла 1 и file2
  • Выполните поиск регулярных выражений по ранее определенной линии с регулярным выражением (однострочный)
  • Как выделить данную строку в данном месте?
  • Является ли удаление Perl Рекомендацией для упрочения системы?
  • Объединить строки между ключевыми словами в однострочные значения, разделенные запятой
  • Как рассчитать (взвешенное) большинство по столбцам?
  • Установка модулей perl
  • Как изменить это решение для Perl, чтобы он заменил встроенные двойные кавычки одиночными кавычками?
  • Найти только сопоставленный шаблон в файле CSV
  • Linux и Unix - лучшая ОС в мире.