Существует ли способ получить минуту, макс., медиану и среднее число списка чисел в единственной команде?

Проверьте Ваш /var/log/kern.log и /var/log/dmesg (или эквиваленты) для любых подсказок. По моему опыту, это произошло со мной только, когда сетевое соединение монтирования NFS внезапно отбросило или разрушенный драйвер устройства. Мог произойти, если поломки жесткого диска также, я верю.

Можно использовать lsof видеть то, что файлы устройств процесс имеют открытый.

97
06.09.2016, 14:04
20 ответов

Можно использовать язык программирования R.

Вот быстрый и грязный сценарий R:

#! /usr/bin/env Rscript
d<-scan("stdin", quiet=TRUE)
cat(min(d), max(d), median(d), mean(d), sep="\n")

Отметьте "stdin" в scan который является специальным именем файла для чтения из стандартного входа (который означает от каналов или перенаправлений).

Теперь можно перенаправить данные по stdin к сценарию R:

$ cat datafile
1
2
4
$ ./mmmm.r < datafile
1
4
2
2.333333

Также работы для плавающих точек:

$ cat datafile2
1.1
2.2
4.4
$ ./mmmm.r < datafile2
1.1
4.4
2.2
2.566667

Если Вы не хотите писать файл сценария R, можно вызвать истинную остроту (с разрывом строки только для удобочитаемости) в использовании командной строки Rscript:

$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' \
          -e 'cat(min(d), max(d), median(d), mean(d), sep="\n")' < datafile
1
4
2
2.333333

Прочитайте прекрасные руководства R по http://cran.r-project.org/manuals.html.

К сожалению, полная ссылка только доступна в PDF. Другой способ считать ссылку путем ввода ?topicname в подсказке интерактивной сессии R.


Для полноты: существует команда R, какие выводы все значения Вы хотите и т.д. К сожалению, в человеческом дружественном формате, который трудно проанализировать программно.

> summary(c(1,2,4))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.500   2.000   2.333   3.000   4.000 
52
27.01.2020, 19:30
  • 1
    Это выглядит интересным.. Я более внимательно рассмотрю в нем завтра.. На основе страницы Википедии, "R стал фактическим стандартом среди статистиков"... хорошо, это - значительная почесть... Я на самом деле попробовал к dowload его на днях (я продолжал видеть, что это упомянуло), но я не мог найти его в Ubuntu repo... Я разовью его завтра... –  Peter.O 25.05.2011, 20:26
  • 2
    в человечности (и debian?) repo пакет назван r-base. –  lesmana 25.05.2011, 20:44
  • 3
    благодарит, мне была нужна та ссылка имени :) Я не думал о r-в синаптическом поле поиска, и это не действует на одинокий символ... Я испытал его теперь, и это выглядит идеальным.. R язык является ясно лучшим для моего требования в этой ситуации.. Согласно ответу Жабр, Rscript интерфейс для сценариев файлов является самым соответствующим (по сравнению с. R, который является интерактивным интерфейсом)..., и R в терминале делает для удобного калькулятора или тестовой среды (как python :) –  Peter.O 26.05.2011, 14:28
  • 4
    (+1), я люблю R. Я не могу рекомендовать это достаточно. –  Dason 03.04.2012, 05:36
  • 5
    или просто cat datafile | Rscript -e 'print(summary(scan("stdin")));' –  shabbychef 12.08.2014, 01:32

Я буду выбор второго lesmana R и предлагать мою первую программу R. Это читает одно число на строку на стандартном входе и пишет четыре числа (минута, макс., среднее число, медиана) разделенный пробелами к стандартному выводу.

#!/usr/bin/env Rscript
a <- scan(file("stdin"), c(0), quiet=TRUE);
cat(min(a), max(a), mean(a), median(a), "\n");
4
27.01.2020, 19:30
  • 1
    Спасибо за "второе" (это заверяет)... Ваш пример был полезен, поскольку я не понял непосредственно это R интерактивный интерфейс, и Rscript управляет файлами в виде сценария, которые могут быть исполняемым файлом согласно Вашему удару хеша в качестве примера, или вызванный из сценария удара.. Сценарии могут обработать командную строку args (например, stackoverflow.com/questions/2045706 / …), таким образом, это выглядит хорошим... Также R выражения может использоваться в ударе через -e ... но я действительно задаюсь вопросом как R выдерживает сравнение с bc ... –  Peter.O 26.05.2011, 05:05

Только ради наличия множества опций, представленных на этой странице, Вот еще два пути:

1: октава

  • Октава GNU является высокоуровневым интерпретируемым языком, прежде всего, предназначенным для числовых вычислений. Это обеспечивает возможности числового решения линейных и нелинейных проблем, и для выполнения других числовых экспериментов.

Вот быстрый пример октавы.

octave -q --eval 'A=1:10;
  printf ("# %f\t%f\t%f\t%f\n", min(A), max(A), median(A), mean(A));'  
# 1.000000        10.000000       5.500000        5.500000

2: колотите + специализированные инструменты.

Чтобы удар обработал числа с плавающей запятой, этот сценарий использование numprocess и numaverage от пакета num-utils.

PS. У меня также был разумный взгляд на bc, но для этого конкретного задания, это ничего не предлагает вне какой awk делает. Это - (как 'c' в 'до н.э' состояниях) калькулятор — калькулятор, который требует большого программирования как awk и этот сценарий удара...


arr=($(sort -n "LIST" |tee >(numaverage 2>/dev/null >stats.avg) ))
cnt=${#arr[@]}; ((cnt==0)) && { echo -e "0\t0\t0\t0\t0"; exit; }
mid=$((cnt/2)); 
if [[ ${cnt#${cnt%?}} == [02468] ]] 
   then med=$( echo -n "${arr[mid-1]}" |numprocess /+${arr[mid]},%2/ )
   else med=${arr[mid]}; 
fi     #  count   min       max           median        average
echo -ne "$cnt\t${arr[0]}\t${arr[cnt-1]}\t$med\t"; cat stats.avg 
5
27.01.2020, 19:30

Минуту, макс. и среднее число довольно легко получить с awk:

% echo -e '6\n2\n4\n3\n1' | awk 'NR == 1 { max=$1; min=$1; sum=0 }
   { if ($1>max) max=$1; if ($1<min) min=$1; sum+=$1;}
   END {printf "Min: %d\tMax: %d\tAverage: %f\n", min, max, sum/NR}'
Min: 1  Max: 6  Average: 3,200000

Вычисление медианы немного более хитро, так как необходимо отсортировать числа и сохранить их всех в памяти некоторое время или считать их дважды (в первый раз для подсчета их, вторыми - для получения среднего значения). Вот пример, который хранит все числа в памяти:

% echo -e '6\n2\n4\n3\n1' | sort -n | awk '{arr[NR]=$1}
   END { if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}' 
3
20
27.01.2020, 19:30
  • 1
    Спасибо... Ваш пример является хорошим вводом к awk для меня.. Я настроил его немного и соединил два (привыкание к awk)... Я использовал awk's asort вместо переданного по каналу sort, и это, кажется, сортирует целые числа и десятичные числа правильно.. Вот является ссылка на мою получающуюся версию paste.ubuntu.com/612674... (И примечание Kim: я экспериментировал с awk в течение нескольких часов теперь. Работа с примером личного интереса является путем лучше ко мне)... Общие сведения читателям: мне все еще интересно видеть другие методы. более компактное лучше. Я буду ожидать некоторое время... –  Peter.O 25.05.2011, 14:06

Я на самом деле имею в наличии немного awk программы для предоставления суммы, количества данных, минимальной данной величины, максимальной данной величины, средней и медиана отдельного столбца числовых данных (включая отрицательные числа):

#!/bin/sh
sort -n | awk '
  BEGIN {
    c = 0;
    sum = 0;
  }
  $1 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/ {
    a[c++] = $1;
    sum += $1;
  }
  END {
    ave = sum / c;
    if( (c % 2) == 1 ) {
      median = a[ int(c/2) ];
    } else {
      median = ( a[c/2] + a[c/2-1] ) / 2;
    }
    OFS="\t";
    print sum, c, ave, median, a[0], a[c-1];
  }
'

Вышеупомянутый сценарий читает из stdin и печати разделенные от вкладки столбцы вывода на одной строке.

53
27.01.2020, 19:30
  • 1
    Ага! это очевидно (теперь, когда я видел Ваш awk сценарий :)... Нет никакой потребности продолжать проверять в течение минуты и макс. когда массив отсортирован :) и это означает что NR==1 может пойти (useless-use-of-if) наряду с минимальными проверками / макс. проверками, таким образом, вся инициализация может быть расположена в разделе BEGIN (хороший!)... Обеспечение комментариев является приятной чертой также.. Спасибо, +1... –  Peter.O 26.05.2011, 05:28
  • 2
    Просто мысль.. возможно, разрешение только численные данные лучше, чем запрещение комментариев (но это зависит Вы Ваши требования).. –  Peter.O 26.05.2011, 09:21
  • 3
    Технически, awk предположит, что "новые" переменные являются нулем, так в этом случае BEGIN{} раздел является ненужным. Я зафиксировал обертывание (никакая потребность выйти из разрывов строки любой). Я также использовал OFS="\t" вымыться print строка и реализованный @Peter. O второй комментарий. (Да, мой regex позволяет ., но как awk интерпретирует это как 0, это приемлемо.) номер –  Adam Katz 15.01.2015, 23:22
  • 4
    @AdamKatz - это большие изменения, но как есть, я не записал программу. Мой awk сценарий теперь существенно отличается. Я почти чувствую, что необходимо приписать себе вышеупомянутую программу для предоставления кредита, где кредит является подлежащим выплате. –  Bruce Ediger 16.01.2015, 00:31

Если Вы больше интересуетесь утилитой вместо того, чтобы быть спокойными или умными, то perl более легкий выбор, чем awk. В общем и целом это будет идти каждый *, отклоняют с последовательным поведением, и легко и свободен установить на окнах. Я думаю, что это также менее загадочно, чем awk, и будут некоторые модули статистики, которые Вы могли использовать, если бы Вы хотели социальную гостиницу между записью его сами и чем-то как R. Мой справедливо непротестированный (на самом деле я знаю, это имеет ошибки, но это работает на мои цели), perl сценарий занял приблизительно минуту для записи, и я предположу, что единственная загадочная часть была бы while(<>), то, которое является очень полезной стенографией, значение берут файл (файлы), передало как параметры командной строки, считайте строку за один раз и поместите ту строку в специальную переменную $_. Таким образом, Вы могли поместить это в файл, названный count.pl, и выполнить его как perl count.pl myfile. Кроме этого должно быть крайне очевидно, что продолжается.

$max = 0;
while (<>) {
 $sum = $sum + $_;
 $max = $_ if ($_ > $max);
 $count++;
}
$avg=$sum/$count;
print "$count numbers total=$sum max=$max mean=$avg\n";
0
27.01.2020, 19:30

Более простой ответ:

r summary file.txt
r -e 'min(d); max(d); median(d); mean(d)' file.txt

Это использует среду R для упрощения статистического анализа.

6
27.01.2020, 19:30
nums=$(<file.txt); 
list=(`for n in $nums; do printf "%015.06f\n" $n; done | sort -n`); 
echo min ${list[0]}; 
echo max ${list[${#list[*]}-1]}; 
echo median ${list[${#list[*]}/2]};
7
27.01.2020, 19:30
  • 1
    echo file.txt не делает взглядов совершенно верно, возможно cat –  malat 17.12.2013, 16:14

Минимум:

jq -s min

Максимум:

jq -s max

Медиана:

sort -n|awk '{a[NR]=$0}END{print(NR%2==1)?a[int(NR/2)+1]:(a[NR/2]+a[NR/2+1])/2}'

Среднее значение:

jq -s add/length

В jq - Параметр s ( - slurp ) создает массив для входных строк после синтаксического анализа каждой строки как JSON или, в данном случае, числа.

19
27.01.2020, 19:30

pythonpy хорошо работает для такого рода вещей:

cat file.txt | py --ji -l 'min(l), max(l), numpy.median(l), numpy.mean(l)'
18
27.01.2020, 19:30

с GNU DataMash :

$ printf '1\n2\n4\n' | datamash max 1 min 1 mean 1 median 1
4   1   2.3333333333333 2
51
27.01.2020, 19:30

И один(длинный) лайнер на Perl, включая медиану:

cat numbers.txt \
| perl -M'List::Util qw(sum max min)' -MPOSIX -0777 -a -ne 'printf "%-7s : %d\n"x4, "Min", min(@F), "Max", max(@F), "Average", sum(@F)/@F,  "Median", sum( (sort {$a<=>$b} @F)[ int( $#F/2 ), ceil( $#F/2 ) ] )/2;'

Используются следующие специальные опции:

  • -0777 : читайте весь файл сразу, а не строку за строкой
  • -a : autosplit в массив @F

Более читабельная версия скрипта будет :

#!/usr/bin/perl

use List::Util qw(sum max min);
use POSIX;

@F=<>;

printf "%-7s : %d\n" x 4,
    "Min", min(@F),
    "Max", max(@F),
    "Average", sum(@F)/@F,
    "Median", sum( (sort {$a<=>$b} @F)[ int( $#F/2 ), ceil( $#F/2 ) ] )/2;

Если вам нужны децималы, замените %d на что-то вроде %. 2f.

7
27.01.2020, 19:30

Ниже сортировка/awk тандем делает это:

sort -n | awk '{a[i++]=$0;s+=$0}END{print a[0],a[i-1],(a[int(i/2)]+a[int((i-1)/2)])/2,s/i}'

(вычисляет медиану как среднее двух центральных значений, если счетчик равен)

2
27.01.2020, 19:30

cat / python единственное решение - не доказательство пустого ввода!

cat data |  python3 -c "import fileinput as FI,statistics as STAT; i = [int(l) for l in FI.input()]; print('min:', min(i), ' max: ', max(i), ' avg: ', STAT.mean(i), ' median: ', STAT.median(i))"
1
27.01.2020, 19:30

Взяв за основу код Брюса, вот более эффективная реализация которая не хранит все данные в памяти.  Как указано в вопросе, предполагается, что входной файл имеет (по крайней мере) одно число в строке.  Он подсчитывает строки во входном файле, которые содержат определяющее число и передает это количество команде awk вместе с (предшествующими) отсортированными данными.  Так, например, если файл содержит

6.0
4.2
8.3
9.5
1.7

то на вход команды awk фактически поступает

5
1.7
4.2
6.0
8.3
9.5

Тогда сценарий awk фиксирует счетчик данных в блоке кода NR==1 и сохраняет среднее значение (или два средних значения, которые усредняются для получения медианы) когда видит их.

FILENAME="Salaries.csv"

(awk 'BEGIN {c=0} $1 ~ /^[-0-9]*(\.[0-9]*)?$/ {c=c+1;} END {print c;}' "$FILENAME"; \
        sort -n "$FILENAME") | awk '
  BEGIN {
    c = 0
    sum = 0
    med1_loc = 0
    med2_loc = 0
    med1_val = 0
    med2_val = 0
    min = 0
    max = 0
  }

  NR==1 {
    LINES = $1
    # We check whether numlines is even or odd so that we keep only
    # the locations in the array where the median might be.
    if (LINES%2==0) {med1_loc = LINES/2-1; med2_loc = med1_loc+1;}
    if (LINES%2!=0) {med1_loc = med2_loc = (LINES-1)/2;}
  }

  $1 ~ /^[-0-9]*(\.[0-9]*)?$/  &&  NR!=1 {
    # setting min value
    if (c==0) {min = $1;}
    # middle two values in array
    if (c==med1_loc) {med1_val = $1;}
    if (c==med2_loc) {med2_val = $1;}
    c++
    sum += $1
    max = $1
  }
  END {
    ave = sum / c
    median = (med1_val + med2_val ) / 2
    print "sum:" sum
    print "count:" c
    print "mean:" ave
    print "median:" median
    print "min:" min
    print "max:" max
  }
'
2
27.01.2020, 19:30

num - это крошечная awk оболочка, которая делает это и многое другое, например

$ echo "1 2 3 4 5 6 7 8 9" | num max
9
$ echo "1 2 3 4 5 6 7 8 9" | num min max median mean
..and so on

это избавляет вас от необходимости изобретать колесо в ультрапортативной awk. Документация приведена выше, а прямая ссылка здесь (также посетите страницу GitHub ]).

2
27.01.2020, 19:30

Сperl:

$ printf '%s\n' 1 2 4 |
   perl -MList::Util=min,max -MStatistics::Basic=mean,median -w -le '
     chomp(@l = <>); print for min(@l), max(@l), mean(@l), median(@l)'
1
4
2.33
2
2
27.01.2020, 19:30

Расширение ответа Нисетамы:

однострочник с jq

jq -s '{ min:min, max:max, sum:add, count:length, avg: (add/length), median: (sort|.[(length/2|floor)])

Пример:

echo 1 2 3 4 | jq -s '{ min:min, max:max, sum:add, count:length, avg: (add/length), median: (sort|.[(length/2|floor)]) }'

Дает вам:

{
  "min": 1,
  "max": 5,
  "sum": 15,
  "count": 5,
  "avg": 3,
  "median": 3
}

Примечание. :Медиана не совсем верна, когда #элементов четно, но достаточно близко, ИМХО.

1
24.09.2020, 20:24

С вкладышем R one -:

R -q -e 'summary(as.numeric(read.table("your_single_col_file")[,1]))'

Например, для моего файла я получил такой вывод:

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  550.4   628.3   733.1   706.5   778.4   832.9
2
06.01.2021, 07:32

Я написал perl-скрипт под названием 'stats', который делает это и многое другое. (и вы можете выбрать нужные биты с помощью таких опций, как «--сумма», «--медиана» и т. д.

$ ls -lR | grep $USER| scut -f=4 | stats 
Sum       1.22435e+08
Number    428
Mean      286064
Median    4135
Mode      0
NModes    4
Min       0
Max       8.47087e+07
Range     8.47087e+07
Variance  1.69384e+13
Std_Dev   4.11563e+06
SEM       198936
95% Conf  -103852 to 675979
          [for a normal distribution (ND) - see skew]
Quantiles (5)
        Index   Value
1       85      659
2       171     2196
3       256     11015
4       342     40210
Skew      20.3201
          [Skew=0 for a symmetric dist]
Std_Skew  171.621
Kurtosis  413.679
          [Kurtosis=3 for a ND]
PopKurt   0.975426
          [Pop'n Kurtosis is normalized to sample size; PK=0 for a ND]

В комплект входит scut (крутая штука для резки/соединения )в :https://github.com/hjmangalam/scut

0
03.06.2021, 05:18

Теги

Похожие вопросы