มีวิธีการรับ min, max, มัธยฐานและค่าเฉลี่ยของรายการตัวเลขในคำสั่งเดียวหรือไม่?


93

ฉันมีรายการตัวเลขในไฟล์หนึ่งรายการต่อบรรทัด ฉันจะรับค่าต่ำสุดสูงสุดค่ามัธยฐานและค่าเฉลี่ยได้อย่างไร ฉันต้องการใช้ผลลัพธ์ในสคริปต์ทุบตี

แม้ว่าสถานการณ์ปัจจุบันของฉันจะเป็นจำนวนเต็ม แต่วิธีแก้ปัญหาสำหรับเลขทศนิยมจะเป็นประโยชน์ในบรรทัด


คำตอบ:


50

คุณสามารถใช้ภาษาการเขียนโปรแกรม 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 

1
มันดูน่าสนใจ .. ฉันจะมองให้ใกล้ขึ้นในวันพรุ่งนี้ .. ตามหน้าของวิกิพีเดียว่า "R ได้กลายเป็นมาตรฐานในหมู่นักสถิติ" ... นั่นเป็นรางวัลที่สำคัญ ... ฉันพยายามที่จะทำมันให้สำเร็จ วันอื่น ๆ (ฉันยังคงเห็นมันพูดถึง) แต่ฉันไม่สามารถหามันได้ใน Ubuntu repo ... ฉันจะติดตามมันในวันพรุ่งนี้ ...
Peter.O

10
ในอูบุนตู (และเดเบียน?) Repo r-baseแพคเกจการตั้งชื่อ
Lesmana

ขอบคุณฉันต้องการชื่ออ้างอิงนั้น :) ฉันไม่คิดว่าในช่องค้นหา synaptic และมันไม่ได้ทำตัวละครโดด ๆ ... ฉันลองตอนนี้แล้วและมันก็ดูดีมาก .. Rภาษาเป็นสิ่งที่ดีที่สุดสำหรับความต้องการของฉันในสถานการณ์นี้ .. ตามคำตอบของ Gilles Rscriptอินเตอร์เฟซไปยังไฟล์สคริปต์นั้นเหมาะสมที่สุด (เทียบกับRซึ่งเป็นส่วนต่อประสานแบบโต้ตอบ) ... และ R ในเครื่องเทอร์มินัล หรือสภาพแวดล้อมการทดสอบ (เช่นงูหลาม :)
Peter.O

(+1) ฉันรักอาร์ฉันไม่สามารถแนะนำได้มากพอ
Dason

6
หรือเพียงแค่cat datafile | Rscript -e 'print(summary(scan("stdin")));'
shabbychef

52

จริง ๆ แล้วฉันเก็บโปรแกรม 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 และพิมพ์คอลัมน์ที่คั่นด้วยแท็บในบรรทัดเดียว


1
Aha! เห็นได้ชัด (ตอนนี้ฉันเห็นสคริปต์ awk ของคุณแล้ว ... ) ไม่จำเป็นต้องตรวจสอบนาทีและสูงสุดเมื่ออาร์เรย์ถูกจัดเรียง :) และนั่นหมายความว่าNR==1สามารถไปได้ (การใช้ที่ไร้ประโยชน์ของ - ถ้า) พร้อมกับการตรวจสอบขั้นต่ำ / สูงสุดดังนั้นการเริ่มต้นทั้งหมดจะอยู่ในส่วน BEGIN (ดี!) ... การอนุญาตให้แสดงความคิดเห็นก็เป็นสิ่งที่ดีเช่นกันขอบคุณ ... +1 +1
Peter.O

แค่คิด .. อาจจะอนุญาตเฉพาะตัวเลขดีกว่าไม่อนุญาตให้
คอมเม้นท์

1
ในทางเทคนิคawkจะถือว่าตัวแปร "ใหม่" เป็นศูนย์ดังนั้นในกรณีนี้BEGIN{}ส่วนที่ไม่จำเป็น ฉันได้แก้ไขการตัด (ไม่จำเป็นต้องยกเว้นการแบ่งบรรทัด) ฉันเคยOFS="\t"ทำความสะอาดprintสายและใช้ความคิดเห็นที่สองของ @ Peter.O (ใช่ regex ของฉันช่วย.แต่awkตีความว่าเป็น0ที่ยอมรับ.)
อดัมแคทซ์

1
@ AdamKatz - สิ่งเหล่านี้เป็นการเปลี่ยนแปลงที่ยอดเยี่ยม แต่เมื่อมันมาถึงฉันก็ไม่ได้เขียนโปรแกรม awkตอนนี้สคริปต์ของฉันแตกต่างอย่างมาก ฉันเกือบรู้สึกว่าคุณควรใช้เครดิตสำหรับโปรแกรมด้านบนเพื่อให้เครดิตเมื่อถึงกำหนดชำระเครดิต
Bruce Ediger

1
ฉันเขียนสคริปต์ perl ที่เรียกว่าavgซึ่งทำสิ่งนี้และอื่น ๆ อีกมาก
Adam Katz

47

ด้วยdatamash ของ GNU :

$ printf '1\n2\n4\n' | datamash max 1 min 1 mean 1 median 1
4   1   2.3333333333333 2

4
คำตอบที่ง่ายที่สุดสำหรับการทุบตีตามที่ถาม
rfabbri

3
brew install datamashให้รุ่นที่ใช้งานได้สำหรับ macOS หากคุณติดตั้ง Hombrew
ต่อ Lundberg

19

ต่ำสุด, สูงสุดและปานกลางนั้นง่ายต่อการรับด้วย 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

ขอบคุณ ... ตัวอย่างของคุณเป็นผู้นำที่ดีในการ awk สำหรับฉัน .. ฉันได้ tweaked มันและทำให้ทั้งสองเข้าด้วยกัน (ได้รับความรู้สึกของ awk) ... ฉันใช้ awk asortมากกว่า piped sortและดูเหมือนว่าจะเรียงลำดับจำนวนเต็มและทศนิยมอย่างถูกต้อง .. นี่คือลิงค์ไปยังรุ่นที่ได้ผลลัพธ์ของฉันpaste.ubuntu.com/612674 ... (และหมายเหตุถึง Kim: ฉันได้ทดลองใช้ awk สองสามชั่วโมงแล้ว . การทำงานกับตัวอย่างผลประโยชน์ส่วนตัวดีกว่าสำหรับฉัน) ... หมายเหตุทั่วไปสำหรับผู้อ่าน: ฉันยังคงสนใจที่จะเห็นวิธีการอื่น มากขึ้นขนาดกะทัดรัดที่ดีกว่า ฉันจะรอสักครู่ ...
Peter.O


17

จำนวนขั้นต่ำ:

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

ใน( ) ตัวเลือกสร้างอาร์เรย์สำหรับเส้นที่นำเข้าที่หลังจากแยกแต่ละบรรทัดเป็น JSON หรือเป็นจำนวนในกรณีนี้jq-s--slurp


3
โซลูชัน jq มีคุณค่าของการกล่าวถึงเป็นพิเศษเนื่องจากเป็นการรวบรัดและใช้เครื่องมือในลักษณะที่ไม่ชัดเจนอีกครั้ง
jplindstrom

1
สวย! หวังว่าฉันจะให้ +2
RASG

7
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]};

echo file.txtอาจดูไม่ถูกต้องอาจจะcat
malat

6

และ 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


6

Simple-rคือคำตอบ:

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

มันใช้สภาพแวดล้อม R เพื่อลดความซับซ้อนของการวิเคราะห์ทางสถิติ


5

เพียงเพื่อให้มีตัวเลือกที่หลากหลายในหน้านี้ต่อไปนี้เป็นสองวิธีเพิ่มเติม:

1: ระดับแปดเสียง

  • GNU Octave เป็นภาษาที่ตีความในระดับสูงโดยมีจุดประสงค์เพื่อการคำนวณเชิงตัวเลขเป็นหลัก มันมีความสามารถในการแก้ปัญหาเชิงตัวเลขของปัญหาเชิงเส้นและไม่เชิงเส้นและสำหรับการดำเนินการทดลองเชิงตัวเลขอื่น ๆ

นี่คือตัวอย่างอ็อกเทฟด่วน

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และจากแพคเกจnumaveragenum-utils

PS ฉันก็มีลักษณะที่สมเหตุสมผลbcแต่สำหรับงานนี้โดยเฉพาะมันไม่ได้ให้อะไรนอกเหนือไปจากสิ่งที่awkทำ มันคือ (เป็น 'c' ใน 'bc' ฯ ) เครื่องคิดเลข - เครื่องคิดเลขที่ต้องมีการเขียนโปรแกรมมาก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 

4

ฉันจะเลือก R ของ Lesmana เป็นครั้งที่สองและเสนอโปรแกรม R แรกของฉัน มันอ่านหนึ่งหมายเลขต่อบรรทัดในอินพุตมาตรฐานและเขียนตัวเลขสี่ตัว (min, max, average, median) คั่นด้วยช่องว่างไปยังเอาต์พุตมาตรฐาน

#!/usr/bin/env Rscript
a <- scan(file("stdin"), c(0), quiet=TRUE);
cat(min(a), max(a), mean(a), median(a), "\n");

ขอบคุณสำหรับ "ที่สอง" (มันทำให้มั่นใจได้) ... ตัวอย่างของคุณมีประโยชน์เพราะฉันไม่ได้ตระหนักถึงสิ่งที่Rเป็นอินเตอร์เฟซแบบโต้ตอบและRscriptไดรฟ์ไฟล์สคริปต์ซึ่งสามารถปฏิบัติการได้ตามตัวอย่างของคุณแฮชปัง หรือถูกเรียกใช้จากภายในสคริปต์ทุบตีสคริปต์สามารถจัดการบรรทัดคำสั่ง (เช่นstackoverflow.com/questions/2045706/ ...... ) ดังนั้นจึงดูดี ... นอกจากนี้ยังสามารถใช้นิพจน์ R ในการทุบตีผ่าน-e... แต่ ฉันสงสัยว่าRจะเปรียบเทียบกับbc...
Peter.O

2

ด้านล่างsort/ 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

การชี้นำจากโค้ดของ Bruce นี่คือการติดตั้งที่มีประสิทธิภาพมากกว่าซึ่งไม่ได้เก็บข้อมูลทั้งหมดไว้ในหน่วยความจำ ตามที่ระบุในคำถามจะถือว่าไฟล์อินพุตมีอย่างน้อยหนึ่งหมายเลขต่อบรรทัด มันจะนับบรรทัดในไฟล์อินพุตที่มีหมายเลขที่มีคุณสมบัติและผ่านการนับไปยัง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
  }
'

ยินดีต้อนรับสู่ Unix & Linux! งานที่ดีสำหรับการโพสต์แรก (1) แม้ว่าสิ่งนี้อาจตอบคำถามได้ แต่มันจะเป็นคำตอบที่ดีกว่าถ้าคุณสามารถอธิบายได้ว่าทำไมมันถึงเป็นเช่นนั้น มาตรฐานของไซต์พัฒนาขึ้นในช่วงสี่ปีที่ผ่านมา ในขณะที่คำตอบที่ใช้รหัสเท่านั้นเป็นที่ยอมรับในปี 2011 เราต้องการคำตอบที่ครอบคลุมซึ่งให้คำอธิบายและบริบทเพิ่มเติม ฉันไม่ได้ขอให้คุณอธิบายสคริปต์ทั้งหมด เพียงส่วนที่คุณเปลี่ยน (แต่ถ้าคุณต้องการอธิบายสคริปต์ทั้งหมดก็ไม่เป็นไร) (BTW ฉันเข้าใจดีฉันขอในนามของผู้ใช้ที่มีประสบการณ์น้อยของเรา) … (ต่อ)
G-Man

(ต่อ) …โปรดอย่าตอบในความคิดเห็น แก้ไขคำตอบของคุณเพื่อให้ชัดเจนและสมบูรณ์ยิ่งขึ้น (2) การแก้ไขสคริปต์เพื่อให้ไม่จำเป็นต้องเก็บทั้งอาร์เรย์ในหน่วยความจำเป็นการปรับปรุงที่ดี แต่ฉันไม่แน่ใจว่าเหมาะสมหรือไม่ที่จะบอกว่าเวอร์ชั่นของคุณ "มีประสิทธิภาพมากขึ้น" เมื่อคุณมีสามcatคำสั่งที่ไม่จำเป็น ดูUUOC … (ต่อ)
G-Man

(ต่อ) ... (3) รหัสของคุณปลอดภัยเนื่องจากคุณตั้งค่าFILENAMEและคุณรู้ว่าสิ่งที่คุณตั้งไว้ แต่โดยทั่วไปคุณควรอ้างอิงตัวแปรเชลล์เสมอเว้นแต่คุณจะมีเหตุผลที่ดีที่จะไม่และคุณแน่ใจว่าคุณรู้ว่าคุณกำลังทำอะไร (4) ทั้งคำตอบของคุณและบรูซไม่สนใจการป้อนข้อมูลเชิงลบ (เช่นตัวเลขที่ขึ้นต้นด้วย-); ไม่มีอะไรในคำถามที่จะแนะนำว่านี่เป็นพฤติกรรมที่ถูกต้องหรือต้องการ อย่ารู้สึกแย่ เป็นเวลากว่าสี่ปีแล้วและเห็นได้ชัดว่าฉันเป็นคนแรกที่สังเกตเห็น
G-Man

ทำการแก้ไขตามคำแนะนำ ไม่ทราบเกี่ยวกับค่าใช้จ่ายของคำสั่ง cat ใช้มันเพื่อสตรีมไฟล์เดียวเสมอ ขอบคุณที่บอกฉันเกี่ยวกับ UUOC .....
Rahul Agarwal

ดี. ฉันยกเลิกรอบที่สามcatและเพิ่มไปยังคำอธิบาย
G-Man

2

The wrapper 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

มันช่วยให้คุณประหยัดเวลาไม่ต้องคิดค้นล้อใหม่ใน ultra-portable awk เอกสารดังกล่าวข้างต้นและลิงค์โดยตรงที่นี่ (ตรวจสอบที่หน้า GitHub ด้วย )


ลิงก์ไปยังรหัสเว็บที่คลุมเครือที่จะดำเนินการในคอมพิวเตอร์ผู้ใช้ดูเหมือนว่าฉันจะเป็นความคิดที่ไม่ดี เว็บไซต์ที่มีรหัสอยู่ที่นี่

รหัส "battletested" นี้ถูกโฮสต์ไว้ที่ไหนก่อนที่จะใส่githubทั้งหมด4เดือนที่ผ่านมา ฉันคิดว่ามันน่าสงสัยอย่างยิ่งที่ลิงก์ไปยัง GitHub ต้องถูกปอกออกจากคำสั่งดาวน์โหลด curl มันง่ายกว่ามากในการหาวิธีบริจาคทางการเงินให้กับนักพัฒนา ดูเหมือนว่าผู้เขียนรหัสนั้นจะกลัวคนอาจไปที่ GitHub และดูประวัติและสถิติ (เกือบจะไม่มีอยู่) มีเหตุผลใดที่จะเรียกการต่อสู้ครั้งนี้ว่านอกเหนือจากการพยายามหาเงินหรือไม่?
Anthon

@BinaryZeba: อัปเดต
coderofsalvation

@Athon ตกลงเอาส่วน 'battletested' ฉันไม่คิดว่านี่เป็นสถานที่สำหรับการวางแผน FUD
coderofsalvation


1

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))"

คุณไม่ได้แสดงค่ามัธยฐาน
Peter.O

@ Peter.O แก้ไขแล้ว
ravwojdyla

สถิติโมดูลต้องรุ่นหลาม> = 3.4
Peter.O

@ Peter.O ถูกต้อง - เป็นปัญหาหรือไม่
ravwojdyla

มันไม่ใช่ปัญหาเว้นแต่ว่าคุณจะไม่มีเวอร์ชั่นไพ ธ อนที่เหมาะสม มันทำให้พกพาน้อยลง
Peter.O

0

หากคุณสนใจในยูทิลิตี้แทนที่จะเป็นเย็นหรือฉลาดแล้วเป็นทางเลือกที่ง่ายกว่าperl awkโดยขนาดใหญ่มันจะอยู่ใน * ระวังด้วยพฤติกรรมที่สอดคล้องกันและเป็นเรื่องง่ายและอิสระในการติดตั้งบน windows ฉันคิดว่ามันยังเป็นความลับน้อยกว่าawkและจะมีโมดูลสถิติบางอย่างที่คุณสามารถใช้ถ้าคุณต้องการบ้านกึ่งกลางระหว่างการเขียนด้วยตัวคุณเองและบางอย่างเช่นอาร์ของฉันยังไม่ทดลองเท่าที่ควร (ในความเป็นจริงฉันรู้ว่ามันมีข้อบกพร่อง ) 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";

3
คุณไม่ได้แสดงค่ามัธยฐาน
Peter.O

0
function median()
{
    declare -a nums=($(cat))
    printf '%s\n' "${nums[@]}" | sort -n | tail -n $((${#nums[@]} / 2 + 1)) | head -n 1
}  

คำตอบนี้จะเป็นประโยชน์หากมีคำอธิบายว่าโค้ดข้างต้นตอบคำถามได้อย่างไรเช่นคุณควรบอกว่าใช้ Bash (ไม่ใช่sh) เป็นล่าม นอกจากนี้ยังมีปัญหาในการอ่านข้อมูลลงในอาเรย์จากไฟล์
Anthony Geoghegan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.