Befehlszeilenprogramm zum Drucken von Statistiken von Zahlen unter Linux

73

Ich finde mich oft mit einer Datei wieder, die eine Nummer pro Zeile hat. Am Ende importiere ich es in Excel, um Dinge wie Median, Standardabweichung usw. anzuzeigen.

Gibt es unter Linux ein Befehlszeilenprogramm, um dasselbe zu tun? Normalerweise muss ich die durchschnittliche, mittlere, minimale, maximale und standardmäßige Abweichung ermitteln.

MK.
quelle
1
Dies ist wahrscheinlich relevant: stackoverflow.com/questions/214363/… .
Oliver Charlesworth
Abstimmung zum Schließen als Tool rec. stats.stackexchange.com/questions/24934/… || serverfault.com/questions/548322/…
Ciro Santilli 法轮功 冠状 病 病. 事件 12.
unix.stackexchange.com/questions/13731/…
Ciro Santilli 法轮功 冠状 病 六四 事件 21
Leute, die sich für diese Frage interessieren jp, könnten auch an einem CLI-Dienstprogramm zum Erstellen von Plots interessiert sein .
Matt Parker

Antworten:

58

Dies ist ein Kinderspiel mit R. Für eine Datei, die so aussieht:

1
2
3
4
5
6
7
8
9
10

Benutze das:

R -q -e "x <- read.csv('nums.txt', header = F); summary(x); sd(x[ , 1])"

Um dies zu bekommen:

       V1       
 Min.   : 1.00  
 1st Qu.: 3.25  
 Median : 5.50  
 Mean   : 5.50  
 3rd Qu.: 7.75  
 Max.   :10.00  
[1] 3.02765
  • Das -qFlag unterdrückt die Startlizenzierung von R und hilft bei der Ausgabe
  • Das -eFlag teilt R mit, dass Sie einen Ausdruck vom Terminal übergeben
  • xist im data.frameGrunde genommen ein Tisch. Es ist eine Struktur, die mehrere Vektoren / Datenspalten enthält, was etwas eigenartig ist, wenn Sie nur einen einzelnen Vektor einlesen. Dies hat Auswirkungen darauf, welche Funktionen Sie verwenden können.
  • Einige Funktionen passen summary()natürlich dazu data.frames. Wenn xmehrere Felder vorhanden summary()wären , würden die obigen beschreibenden Statistiken für jedes Feld bereitgestellt.
  • Es sd()kann jedoch immer nur ein Vektor gleichzeitig verwendet werden, weshalb ich xfür diesen Befehl indiziere ( x[ , 1]gibt die erste Spalte von zurück x). Sie können apply(x, MARGIN = 2, FUN = sd)die SDs für alle Spalten abrufen.
Matt Parker
quelle
Vielen Dank. Ich habe seitdem angefangen, R zu verwenden, und ich denke, es ist ein großartiges Werkzeug, um Daten zu verstehen
MK.
4
Um die zusätzliche Suche zu speichern, wie man R auf Ubuntu bekommt:sudo apt-get install r-base
E-rich
1
R ist vielleicht nett, um in Zukunft mehr zu verwenden, aber ich vermute, es ist eine riesige Bibliotheksinstallation, also hatte ich stunten Gedanken über die Installation des Formulars. Nicht im Zusammenhang mit diesem Kommentar, aber meine brew install Rknapp eine Stunde auf einem MacBook Pro Mid 2015 10.12.5 2.5GHz i7 16GB mit Chrome, Atom und anderen geöffneten Apps. Das meiste davon wurde damit verbracht, einen gcc jit Patch mit dem Xcode CLT O_o zu erstellen, aber jetzt verwende ich gerne Teile dieser Antwort :)
Pysis
Hier ist ein Blog-Beitrag zum allgemeinen Daten-Wrangling mit Bash-Tools , der für Leute von Interesse sein könnte, die diese Frage gefunden haben.
Matt Parker
43

Verwenden von "st" ( https://github.com/nferraz/st )

$ st numbers.txt
N    min   max   sum   mean  stddev
10   1     10    55    5.5   3.02765

Oder:

$ st numbers.txt --transpose
N      10
min    1
max    10
sum    55
mean   5.5
stddev 3.02765

(HAFTUNGSAUSSCHLUSS: Ich habe dieses Tool geschrieben :))

user2747481
quelle
Alle Informationen zur Installation für Neulinge
NeDark
2
Wenn Sie Homebrew verwenden, ist die Installation so einfach wie brew install st.
Jason Axelson
1
Beachten Sie, dass stsich auch darauf beziehen kann simple terminal.
Skippy le Grand Gourou
36

Für den Durchschnitt, den Median und die Standardabweichung können Sie verwenden awk. Dies ist in der Regel schneller als RLösungen. Zum Beispiel wird der Durchschnitt wie folgt gedruckt:

awk '{a+=$1} END{print a/NR}' myfile

( NRist eine awkVariable für die Anzahl der Datensätze, $1bedeutet das erste (durch Leerzeichen getrennte) Argument der Zeile ( $0wäre die gesamte Zeile, was auch hier funktionieren würde, aber im Prinzip weniger sicher wäre, obwohl es für die Berechnung wahrscheinlich nur wäre nehmen Sie das erste Argument sowieso) und ENDbedeutet , dass die folgenden Befehle ein, nachdem sie die gesamte Datei verarbeitet werden , ausgeführt werden (man auch hätte initialisiert , aum 0in einer BEGIN{a=0}Erklärung)).

Hier ist ein einfaches awkSkript, das detailliertere Statistiken bereitstellt (nimmt eine CSV-Datei als Eingabe, andernfalls ändert sie sich FS):

#!/usr/bin/awk -f

BEGIN {
    FS=",";
}
{
   a += $1;
   b[++i] = $1;
}
END {
    m = a/NR; # mean
    for (i in b)
    {
        d += (b[i]-m)^2;
        e += (b[i]-m)^3;
        f += (b[i]-m)^4;
    }
    va = d/NR; # variance
    sd = sqrt(va); # standard deviation
    sk = (e/NR)/sd^3; # skewness
    ku = (f/NR)/sd^4-3; # standardized kurtosis
    print "N,sum,mean,variance,std,SEM,skewness,kurtosis"
    print NR "," a "," m "," va "," sd "," sd/sqrt(NR) "," sk "," ku
}

Es ist einfach, diesem Skript min / max hinzuzufügen, aber es ist genauso einfach, sort& head/ tail :

sort -n myfile | head -n1
sort -n myfile | tail -n1
Skippy le Grand Gourou
quelle
22

Ein weiteres Tool, das zur Berechnung von Statistiken und zur Verteilung von Ansichten im ASCII-Modus verwendet werden kann, ist ministat . Es ist ein Tool von FreeBSD, aber es ist auch für die beliebte Linux-Distribution wie Debian / Ubuntu gepackt. Oder Sie können es einfach herunterladen und aus Quellen erstellen - es sind nur ein C-Compiler und die C-Standardbibliothek erforderlich.

Anwendungsbeispiel:

$ cat test.log 
Handled 1000000 packets.Time elapsed: 7.575278
Handled 1000000 packets.Time elapsed: 7.569267
Handled 1000000 packets.Time elapsed: 7.540344
Handled 1000000 packets.Time elapsed: 7.547680
Handled 1000000 packets.Time elapsed: 7.692373
Handled 1000000 packets.Time elapsed: 7.390200
Handled 1000000 packets.Time elapsed: 7.391308
Handled 1000000 packets.Time elapsed: 7.388075

$ cat test.log| awk '{print $5}' | ministat -w 74
x <stdin>
+--------------------------------------------------------------------------+
| x                                                                        |
|xx                                   xx    x x                           x|
|   |__________________________A_______M_________________|                 |
+--------------------------------------------------------------------------+
    N           Min           Max        Median           Avg        Stddev
x   8      7.388075      7.692373       7.54768     7.5118156    0.11126122
Aliaksei Ramanau
quelle
17

Ja, es heißt Perl
und hier ist ein prägnanter Einzeiler:

perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";'

Beispiel

$ cat tt
1
3
4
5
6.5
7.
2
3
4

Und der Befehl

cat tt | perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";'
records:9
sum:35.5
avg:3.94444444444444
std:1.86256162380447
med:4
max:7.
min:1
bua
quelle
20
Ich bin mir sicher, dass das funktioniert, aber wenn ich alles in einer Zeile mache, bluten meine Augen. Warum nicht ein Skript erstellen, anstatt diese Gräueltat?
Oliver Charlesworth
18
Ich bin mir ziemlich sicher, dass "funktionale Sprachen"! = "Schreiben Sie alles so knapp wie möglich in eine Zeile".
Oliver Charlesworth
10
Nur weil Sie etwas in einer Zeile tun können , heißt das nicht, dass Sie es tun sollten.
Mike Monkiewicz
8
Oneliner sind definitiv nicht zum Lesen. Aber sie sind großartig, um sie einfach in meinen Kitt zu kopieren und einzufügen und die Statistiken einiger Zahlen aus dem Apache-Protokoll zu erhalten ... Also bua roxx
Vajk Hermecz
3
Die Befehlszeile (zumindest Bash) unterstützt auch mehrzeilige Zeichenfolgen. Verwenden Sie einfach einen Zeilenumbruch im Literal.
Paŭlo Ebermann
14

Bedeuten:

awk '{sum += $1} END {print "mean = " sum/NR}' filename

Median:

gawk -v max=128 '

    function median(c,v,    j) { 
       asort(v,j) 
       if (c % 2) return j[(c+1)/2]
       else return (j[c/2+1]+j[c/2])/2.0
    }

    { 
       count++
       values[count]=$1
       if (count >= max) { 
         print  median(count,values); count=0
       } 
    } 

    END { 
       print  "median = " median(count,values)
    }
    ' filename

Modus:

awk '{c[$1]++} END {for (i in count) {if (c[i]>max) {max=i}} print "mode = " max}' filename

Diese Modusberechnung erfordert eine gerade Anzahl von Stichproben, aber Sie sehen, wie es funktioniert ...

Standardabweichung:

awk '{sum+=$1; sumsq+=$1*$1} END {print "stdev = " sqrt(sumsq/NR - (sum/NR)**2)}' filename
Ghoti
quelle
2
Gut gemacht - und mit einem Tool, das in jeder Linux-Distribution verfügbar ist.
Rbellamy
1
@rbellamy - danke! Und nicht nur Linux - ich verwalte FreeBSD-Systeme, bei denen die Unterscheidung zwischen awkund gawkwichtig ist (da Plain Old Awk auf BSD dies nicht beinhaltet asort()).
Ghoti
11

Noch ein Tool: https://www.gnu.org/software/datamash/

# Example: calculate the sum and mean of values 1 to 10:
$ seq 10 | datamash sum 1 mean 1
55 5.5

Könnte häufiger verpackt sein (das erste Tool, das ich zumindest für nix vorverpackt fand)

olejorgenb
quelle
8

Für alle Fälle gibt es datastatein einfaches Programm für Linux, das einfache Statistiken über die Befehlszeile berechnet. Zum Beispiel,

cat file.dat | datastat

gibt den Durchschnittswert über alle Zeilen für jede Spalte von file.dat aus. Wenn Sie die Standardabweichung, Minimal-, Maximal- wissen müssen, können Sie die hinzufügen --dev, --minund --maxOptionen auf.

datastathat die Möglichkeit, Zeilen basierend auf dem Wert einer oder mehrerer "Schlüssel" -Spalten zu aggregieren. Zum Beispiel,

cat file.dat | datastat -k 1

erzeugt für jeden unterschiedlichen Wert in der ersten Spalte (den "Schlüssel") den Durchschnitt aller anderen Spaltenwerte, die unter allen Zeilen mit demselben Wert auf dem Schlüssel zusammengefasst sind. Sie können mehr Spalten als Schlüsselfelder verwenden (z. B. -k 1-3, -k 2,4 usw.).

Es ist in C ++ geschrieben, läuft schnell und mit geringem Speicherbedarf und kann gut mit anderen Tools wie z cut , grep, sed, sort, awkusw.

Tommaso
quelle
Stilistische kleine Erschütterung für den nutzlosen Gebrauch voncat
Tripleee
8

data_hacks ist ein Python-Befehlszeilenprogramm für grundlegende Statistiken.

Das erste Beispiel auf dieser Seite liefert die gewünschten Ergebnisse:

$ cat /tmp/data | histogram.py
# NumSamples = 29; Max = 10.00; Min = 1.00
# Mean = 4.379310; Variance = 5.131986; SD = 2.265389
# each * represents a count of 1
    1.0000 -     1.9000 [     1]: *
    1.9000 -     2.8000 [     5]: *****
    2.8000 -     3.7000 [     8]: ********
    3.7000 -     4.6000 [     3]: ***
    4.6000 -     5.5000 [     4]: ****
    5.5000 -     6.4000 [     2]: **
    6.4000 -     7.3000 [     3]: ***
    7.3000 -     8.2000 [     1]: *
    8.2000 -     9.1000 [     1]: *
    9.1000 -    10.0000 [     1]: *
Matt Parker
quelle
7

Sie können auch Clistats verwenden . Es ist ein hoch konfigurierbares Befehlszeilenschnittstellentool zum Berechnen von Statistiken für einen Strom von begrenzten Eingabenummern.

E / A-Optionen

  • Eingabedaten können aus einer Datei, einer Standardeingabe oder einer Pipe stammen
  • Die Ausgabe kann in eine Datei, eine Standardausgabe oder eine Pipe geschrieben werden
  • Die Ausgabe verwendet Header, die mit "#" beginnen, um das Piping zum Gnuplot zu ermöglichen

Analyseoptionen

  • Signal-, Dateiende- oder Leerzeilenerkennung, um die Verarbeitung zu stoppen
  • Kommentar- und Trennzeichen können festgelegt werden
  • Spalten können aus der Verarbeitung herausgefiltert werden
  • Zeilen können basierend auf numerischen Einschränkungen aus der Verarbeitung herausgefiltert werden
  • Zeilen können basierend auf der Zeichenfolgenbeschränkung aus der Verarbeitung herausgefiltert werden
  • Anfängliche Kopfzeilen können übersprungen werden
  • Eine feste Anzahl von Zeilen kann verarbeitet werden
  • Doppelte Trennzeichen können ignoriert werden
  • Zeilen können in Spalten umgeformt werden
  • Erzwingen Sie strikt, dass nur Zeilen derselben Größe verarbeitet werden
  • Eine Zeile mit Spaltentiteln kann zum Betiteln von Ausgabestatistiken verwendet werden

Statistikoptionen

  • Zusammenfassende Statistik (Anzahl, Minimum, Mittelwert, Maximum, Standardabweichung)
  • Kovarianz
  • Korrelation
  • Versatz der kleinsten Quadrate
  • Neigung der kleinsten Quadrate
  • Histogramm
  • Rohdaten nach dem Filtern

HINWEIS: Ich bin der Autor.

dpmcmlxxvi
quelle
6

Ich wollte dies in einer Shell-Pipeline tun, und es dauerte eine Weile, bis ich die richtigen Argumente für R gefunden hatte. Folgendes habe ich mir ausgedacht:

seq 10 | R --slave -e 'x <- scan(file="stdin",quiet=TRUE); summary(x)' Min. 1st Qu. Median Mean 3rd Qu. Max. 1.00 3.25 5.50 5.50 7.75 10.00

Die --slaveOption "Lass (s) R so leise wie möglich laufen ... Es impliziert --quiet und --no-save." Die -eOption weist R an, die folgende Zeichenfolge als R-Code zu behandeln. Die erste Anweisung liest vom Standard in und speichert, was in der Variablen "x" gelesen wird. Die quiet=TRUEOption für die scanFunktion unterdrückt das Schreiben einer Zeile, in der angegeben ist, wie viele Elemente gelesen wurden. Die zweite Anweisung wendet die summaryFunktion an x, die die Ausgabe erzeugt.

Jose Quinteiro
quelle
3
#!/usr/bin/perl
#
# stdev - figure N, min, max, median, mode, mean, & std deviation
#
# pull out all the real numbers in the input
# stream and run standard calculations on them.
# they may be intermixed with other test, need
# not be on the same or different lines, and 
# can be in scientific notion (avagadro=6.02e23).
# they also admit a leading + or -.
#
# Tom Christiansen
# [email protected]

use strict;
use warnings;

use List::Util qw< min max >;

#
my $number_rx = qr{

  # leading sign, positive or negative
    (?: [+-] ? )

  # mantissa
    (?= [0123456789.] )
    (?: 
        # "N" or "N." or "N.N"
        (?:
            (?: [0123456789] +     )
            (?:
                (?: [.] )
                (?: [0123456789] * )
            ) ?
      |
        # ".N", no leading digits
            (?:
                (?: [.] )
                (?: [0123456789] + )
            ) 
        )
    )

  # abscissa
    (?:
        (?: [Ee] )
        (?:
            (?: [+-] ? )
            (?: [0123456789] + )
        )
        |
    )
}x;

my $n = 0;
my $sum = 0;
my @values = ();

my %seen = ();

while (<>) {
    while (/($number_rx)/g) {
        $n++;
        my $num = 0 + $1;  # 0+ is so numbers in alternate form count as same
        $sum += $num;
        push @values, $num;
        $seen{$num}++;
    } 
} 

die "no values" if $n == 0;

my $mean = $sum / $n;

my $sqsum = 0;
for (@values) {
    $sqsum += ( $_ ** 2 );
} 
$sqsum /= $n;
$sqsum -= ( $mean ** 2 );
my $stdev = sqrt($sqsum);

my $max_seen_count = max values %seen;
my @modes = grep { $seen{$_} == $max_seen_count } keys %seen;

my $mode = @modes == 1 
            ? $modes[0] 
            : "(" . join(", ", @modes) . ")";
$mode .= ' @ ' . $max_seen_count;

my $median;
my $mid = int @values/2;
if (@values % 2) {
    $median = $values[ $mid ];
} else {
    $median = ($values[$mid-1] + $values[$mid])/2;
} 

my $min = min @values;
my $max = max @values;

printf "n is %d, min is %g, max is %d\n", $n, $min, $max;
printf "mode is %s, median is %g, mean is %g, stdev is %g\n", 
    $mode, $median, $mean, $stdev;
tchrist
quelle
3

Es gibt auch simple-r, das fast alles kann, was R kann, aber mit weniger Tastenanschlägen:

https://code.google.com/p/simple-r/

Um grundlegende beschreibende Statistiken zu berechnen, müsste man Folgendes eingeben:

r summary file.txt
r summary - < file.txt
cat file.txt | r summary -

Für jede Abweichung von Durchschnitt, Median, Min, Max und Standard wäre der Code:

seq 1 100 | r mean - 
seq 1 100 | r median -
seq 1 100 | r min -
seq 1 100 | r max -
seq 1 100 | r sd -

Bekommt kein einfaches R!

Tom
quelle
Komisch, es ist ein Perl-Wrapper für R. R ist keine Programmiersprache! > :-)
Ciro Santilli 法轮功 冠状 病 六四. 法轮功
2

Verwenden von xsv :

$ echo '3 1 4 1 5 9 2 6 5 3 5 9' |tr ' ' '\n' > numbers-one-per-line.csv

$ xsv stats -n < numbers-one-per-line.csv 
field,type,sum,min,max,min_length,max_length,mean,stddev
0,Integer,53,1,9,1,1,4.416666666666667,2.5644470922381863

# mode/median/cardinality not shown by default since it requires storing full file in memory:
$ xsv stats -n --everything < numbers-one-per-line.csv | xsv table
field  type     sum  min  max  min_length  max_length  mean               stddev              median  mode  cardinality
0      Integer  53   1    9    1           1           4.416666666666667  2.5644470922381863  4.5     5     7
Unhammer
quelle
1
Die Installation mit brewaufgedeckten Abhängigkeiten. Ziemlich "schwer" für diese Funktionalität.
Alex Moore-Niemi
Also kein Gebräu verwenden? github.com/BurntSushi/xsv/releases hat vorkompilierte Binärdateien für Macos, daher sollte es keinen Grund geben, die vollständige Rost-Toolchain zu installieren oder was auch immer gebraut wird.
Unhammer
2

Ein weiteres Tool: tsv-summarize aus den tsv-Dienstprogrammen von eBay . Min, Max, Mittelwert, Median und Standardabweichung werden unterstützt. Bestimmt für große Datenmengen. Beispiel:

$ seq 10 | tsv-summarize --min 1 --max 1 --median 1 --stdev 1
1    10    5.5    3.0276503541

Haftungsausschluss: Ich bin der Autor.

JonDeg
quelle
0

Auch die Self-Write- Statistiken (zusammen mit 'scut') sind ein Perl-Util, um genau das zu tun. Mit einem Strom von Zahlen auf STDIN gefüttert, versucht es, Nicht-Zahlen abzulehnen und gibt Folgendes aus:

$ ls -lR | scut -f=4 | stats
Sum       3.10271e+07
Number    452
Mean      68643.9
Median    4469.5
Mode      4096
NModes    6
Min       2
Max       1.01171e+07
Range     1.01171e+07
Variance  3.03828e+11
Std_Dev   551206
SEM       25926.6
95% Conf  17827.9 to 119460
          (for a normal distribution - see skew)
Skew      15.4631
          (skew = 0 for a symmetric dist)
Std_Skew  134.212
Kurtosis  258.477
          (K=3 for a normal dist)

Es kann auch eine Reihe von Transformationen für den Eingabestream durchführen und nur den schmucklosen Wert ausgeben, wenn Sie danach fragen. dh 'stats --mean' gibt den Mittelwert als unbeschrifteten Float zurück.

Harry Mangalam
quelle