Astrophysiker
Anmeldungsdatum: 8. Januar 2007
Beiträge: 517
Wohnort: Bonn
|
Hallo, ich würde gerne über mehrere Messreihen, die in einer Datei gespeichert sind mitteln. Die Datei sieht ungefähr so aus:
0.000000 0.000000
0.250000 75039.000000
0.500000 50026.000000
0.750000 50026.000000
1.000000 50026.000000
1.250000 50026.000000
1.500000 -25013.000000
1.750000 50026.000000
2.000000 50026.000000
0.000000 0.000000
0.250000 75059.000000
0.500000 50135.000000
0.750000 50714.000000
1.000000 50105.000000
1.250000 50158.000000
1.500000 -25003.000000
1.750000 50020.000000
2.000000 50027.000000
...
Ich würde jetzt gerne für die Werte der ersten Spalte jeweils den Mittelwert der Werte der 2. Spalte bestimmen. Ich dachte dabei an ein Array, nur leider funktioniert das nicht...
{sum[$1]+=$2}
Lasse ich mir am Schluss die Werte ausgeben, so sind alle Einträge des Arrays leer. Hat jemand eine Rat für mich? Es sind ca. 250 Werte pro Messreihe und etwa 20-200 Messreihen, die möchte ich ungern von Hand berechnen 😛 Grüße,
Astrophysiker
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4695
Wohnort: Berlin
|
@Astrophysiker: Ich verstehe die Aufgabenstellung nicht so ganz. Was bedeutet "für die Werte der ersten Spalte jeweils den Mittelwert der Werte der 2. Spalte bestimmen"? Möchtest Du den Mittelwert der beiden Werte jeder Spalte? Also ein Ergebnis pro Zeile? Oder den Mittelwert aller Werte pro Spalte? Also zwei Werte als Ergebnis? Ich würde so etwas eher mit einer "richtigen" Programmiersprache angehen. Bei den dynamischen kann man so etwas ja auch interaktiv erledigen. Zum Beispiel mit Python und dem numpy -Package, das Klassen und Funktionen für's Rechnen mit Arrays bereit stellt. Kleine Sitzung in der ipython -Shell: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | In [409]: import numpy as np
In [410]: a = np.fromfile('test.txt', sep=' ')
In [411]: a
Out[411]:
array([ 0.00000000e+00, 0.00000000e+00, 2.50000000e-01,
7.50390000e+04, 5.00000000e-01, 5.00260000e+04,
7.50000000e-01, 5.00260000e+04, 1.00000000e+00,
5.00260000e+04, 1.25000000e+00, 5.00260000e+04,
1.50000000e+00, -2.50130000e+04, 1.75000000e+00,
5.00260000e+04, 2.00000000e+00, 5.00260000e+04])
In [412]: a.shape = (len(a) / 2, 2)
In [413]: a
Out[413]:
array([[ 0.00000000e+00, 0.00000000e+00],
[ 2.50000000e-01, 7.50390000e+04],
[ 5.00000000e-01, 5.00260000e+04],
[ 7.50000000e-01, 5.00260000e+04],
[ 1.00000000e+00, 5.00260000e+04],
[ 1.25000000e+00, 5.00260000e+04],
[ 1.50000000e+00, -2.50130000e+04],
[ 1.75000000e+00, 5.00260000e+04],
[ 2.00000000e+00, 5.00260000e+04]])
In [414]: np.average(a, -1)
Out[414]:
array([ 0. , 37519.625, 25013.25 , 25013.375, 25013.5 ,
25013.625, -12505.75 , 25013.875, 25014. ])
In [415]: np.average(a, -2)
Out[415]: array([ 1.00000000e+00, 3.89091111e+04])
|
|
Astrophysiker
(Themenstarter)
Anmeldungsdatum: 8. Januar 2007
Beiträge: 517
Wohnort: Bonn
|
Ok, ich hol mal etwas weiter aus. Ich messe in Abhängigkeit der Position (1. Spalte) eine Frequenzverschiebung (2. Spalte), jeweils von 0mm bis 100mm. Das ganze mache ich mindestens 20 mal, habe also für jeden Positionswert mindestens 20 Frequenzwerte. Und über diese Frequenzwerte möchte ich mitteln, sodass ich für jeden Positionswert einen gemittelten Frequenzwert habe. Als Ergebnis hätte ich also gerne zu jedem der 100 Positionswerte einen Frequenzwert.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4695
Wohnort: Berlin
|
Also hast Du zum Beispiel 20 Dateien, bei denen die Werte in der ersten Spalte immer gleich ist (Position) und die in der zweiten Spalte unterschiedlich und Du möchtest als Ergebnis eine Datei mit einer Kopiel der ersten Spalte, ist ja egal aus welcher Datei, und als zweite Spalte den Mittelwert von Spalte zwei aus allen 20 Dateien? Aufgabe richtig verstanden?
|
Astrophysiker
(Themenstarter)
Anmeldungsdatum: 8. Januar 2007
Beiträge: 517
Wohnort: Bonn
|
Ja, nur steht alles in einer Datei, die einzelnen Messreihen sind durch 2 Leerzeilen getrennt.
|
zimon23
Anmeldungsdatum: 8. Dezember 2007
Beiträge: 29
|
Astrophysiker schrieb: Ok, ich hol mal etwas weiter aus. Ich messe in Abhängigkeit der Position (1. Spalte) eine Frequenzverschiebung (2. Spalte), jeweils von 0mm bis 100mm. Das ganze mache ich mindestens 20 mal, habe also für jeden Positionswert mindestens 20 Frequenzwerte. Und über diese Frequenzwerte möchte ich mitteln, sodass ich für jeden Positionswert einen gemittelten Frequenzwert habe. Als Ergebnis hätte ich also gerne zu jedem der 100 Positionswerte einen Frequenzwert.
Wenn ich Dein Problem richtig verstehe hast Du folgendes Dateischema: pos1 freq1a
pos2 freq2a
pos3 freq3a
pos1 freq1b
pos2 freq2b
pos3 freq3b
... Und nun möchtest Du von jedem Block freq1 (also freq1a, freq1b,...) gemittelt haben. und das für alle Frequenzen. Mit perl würde ich das Problem so lösen:
#!/usr/bin/perl
open(FILE,"<$ARGV[0]");
my @lines = <FILE>;
close(FILE);
my %averages = {};
my %averageCount = {};
foreach(@lines){
@line = split(" ",$_);
$averages{$line[0]}+=$line[1];
$averageCount{$line[0]}++;
}
foreach my $key (sort keys %averages){
print "pos: $key, value: ".$averages{$key}/$averageCount{$key}."\n";
}
Die Ausgabe kann man natürlich noch anpassen. Der Aufruf erfolgt dann mit:
average.pl datei.txt
Wobei das oben angegebene Script als average.pl gespeichert sein muss und Ausführungsrechte benötigt (kann man mit dem Befehl chmod +x average.pl geben) Mit awk müsste es ähnlich mit den assoziativen Arrays funktionieren:
{avg[$1]+=$2; avgcount[$1]++} END{asorti(avg[]); for(i in avg){print i" "avg[i]/avgcount[i]}} Gruß zimon
|
Astrophysiker
(Themenstarter)
Anmeldungsdatum: 8. Januar 2007
Beiträge: 517
Wohnort: Bonn
|
zimon23 schrieb: Mit awk müsste es ähnlich mit den assoziativen Arrays funktionieren:
{avg[$1]+=$2; avgcount[$1]++} END{asorti(avg[]); for(i in avg){print i" "avg[i]/avgcount[i]}}
Ja, das funktioniert soweit, bis auf das sortieren...
Mit der asorti-Funktion bekomme ich folgende Meldung:
schedler@LCARS:~$ ./avg.sh messung-250.txt
gawk: Kommandozeile:5: END{asorti(avg[]);
gawk: Kommandozeile:5: ^ syntax error
gawk: Kommandozeile:5: Fatal: Ungültiger Index-Ausdruck.
Ich stelle mal Messdaten und Skript online, dann ist das einfacher für euch:
http://astrophysiker.as.funpic.de/messung-250.txt http://astrophysiker.as.funpic.de/avg.sh
|
zimon23
Anmeldungsdatum: 8. Dezember 2007
Beiträge: 29
|
Dann lass das asorti einfach weg und sortiere zum Schluss mit sort. also:
{avg[$1]+=$2; avgcount[$1]++} END{for(i in avg){print i" "avg[i]/avgcount[i]}}
und Aufruf mit
schedler@LCARS:~$ ./avg.sh messung-250.txt | sort Gruß zimon
|
Astrophysiker
(Themenstarter)
Anmeldungsdatum: 8. Januar 2007
Beiträge: 517
Wohnort: Bonn
|
Jop als Grundgerüst ist das schon mal sehr gut. Ich danke euch für die schnellen Antworten 😉 Gruß,
Astro
|