Seite 1 von 1
Script mehrfach ausführen und Median berechnen.
Verfasst: Montag 19. August 2019, 13:54
von Schwervisuell
Guten Tag liebe Mitglieder des Python-Forums,
wie ihr dem Code sicherlich gleich entnehmen könnt, bin ich noch sehr neu in der Materie des Programmierens. Ich möchte gerne das folgende Script mehrfach (um genau zu sein mehrere hundert mal) nacheinander durchführen, jeweils die Abweichung "zwischenspeichern" und dann anschließend den Median daraus bilden.
Code: Alles auswählen
import numpy
import math
n = Anzahl Punkte
x = numpy.random.uniform(-1, 1, (n, 1))
y = numpy.random.uniform(-1, 1, (n, 1))
kreis = (x)**2 + (y)**2 <= 1
xin = x[kreis]
yin = y[kreis]
pi = (4 * numpy.sum(kreis) / n)
print("Approximiertes Pi:", pi)
print("Faktisches Pi:", round(math.pi, 10))
print("Abweichung:", abs(pi - round(math.pi, 10)))
Würde mich sehr freuen, wenn mir da jemand helfen könnte. Wäre auch schon für das ein oder andere Schlagwort dankbar, nachdem ich dann googeln könnte
Mit freundlichen Grüßen
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Montag 19. August 2019, 14:49
von __blackjack__
@Schwervisuell: Die Stichworte wären Funktionen, also selber eine schreiben, und Schleifen, um die selbst geschriebene Funktion dann mehrere hundert mal aufzurufen.
Wobei falls das jetzt nicht den Arbeitsspeicher sprengt: Du könntest statt das mehrere hundert mal aufzurufen auch eine weitere Dimension zu den Daten hinzufügen und die Schleife effektiv in Numpy ”verschieben”.
`xin` und `yin` werden definiert, aber nicht verwendet.
Die Klammern um `x` und `y` bei der Berechnung von `kreis` machen keinen Sinn. `kreis` ist auch kein so wirklich guter Name. `n` auch nicht zwingend. Verwende sprechende Bezeichner die aussagen was die Werte bedeuten. Also beispielsweise `anzahl_punkte` statt `n`. Bei `kreis` fällt mir so auf Anhieb nichts passendes ein, was ein Hinweis auf eine nicht ganz so günstige Aufteilung des Codes sein könnte. Wenn man das Aufsummieren dort schon macht, könnte man es `anzahl_punkte_im_kreis` nennen.
`round` braucht man nur recht selten wenn man wirklich mit einer gerundeten Zahl *weiterrechnen* will. Nachkommastellen für die Ausgabe legt man bei der Formatierung der Ausgabe als Zeichenkette fest. Beim Platzhalter für die `format()`-Methode oder ab Python 3.6 auch in f-Zeichenkettenliteralen.
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Montag 19. August 2019, 15:06
von Sirius3
Beim Runden stellt sich mir die Frage, warum man unbedingt die Abweichung von auf 10 Stellen gerundetes PI wissen will.
`kreis` würde ich `punkte_innerhalb_kreis_maske` nennen.
Auch die Klammern bei der Berechnung von `pi` machen keinen Sinn. `pi` würde ich hier der Klarheit `genaehertes_pi´ nennen.
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Montag 19. August 2019, 17:09
von Schwervisuell
@__blackjack__
vielen Dank für deine Hinweise. Xin und Yin waren fürs spätere plotten - hab vergessen, den Bereich herauszunehmen, bevor ich den Beitrag gepostet habe. Die Bezeichnungen habe ich eindeutiger gestaltet (was mir tatsächlich sehr geholfen hat... werde ich zukünftig immer so machen).
Das mit den Funktionen und Schleifen habe ich versucht umzusetzen. Ich habe es so gelöst, dass das Script mir die Daten in eine externe .csv schreibt. Den Median würde ich dann einfach stumpf über Excel ausspucken lassen (oder von nem anderen Script). Damit gibts allerdings auch ein kleines Problem (siehe @Alle)
@Sirius3
vielen Dank - die Rundung sowie die überschüssigen Klammern habe ich entfernt.
@Alle
Dank eures Inputs bin ich schon deutlich weiter gekommen. Habe jetzt aber noch das Problem, dass die aktuelle Schleife 10x den gleichen Wert in eine .csv packt statt die Funktion 10 mal auszuführen und dann immer wieder den neuen Wert einzutragen. Vielleicht könnt ihr mir da nochmal helfen? Schonmal vielen Dank.
Code: Alles auswählen
# Python 3.7.4
anzahl_punkte = 50000
x = numpy.random.uniform(-1, 1, (anzahl_punkte, 1))
y = numpy.random.uniform(-1, 1, (anzahl_punkte, 1))
in_kreis = x**2 + y**2 <= 1
pi = (4 * numpy.sum(in_kreis) / anzahl_punkte)
abw = abs(pi - math.pi)
string_abw = str(abw)
def werte_schreiben(string_abw):
zwischenergebnisse = open("Zwischenpuffer.csv", "a")
zwischenergebnisse.write(string_abw)
zwischenergebnisse.write("\n")
zwischenergebnisse.close()
anzahl_simulationen = 0
maximalanzahl_simulationen = 10
while anzahl_simulationen < maximalanzahl_simulationen:
anzahl_simulationen = anzahl_simulationen + 1
werte_schreiben(string_abw)
Vielen, vielen Dank schonmal.
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Montag 19. August 2019, 17:28
von __blackjack__
@Schwervisuell: Wieso sollte das nicht 10 mal das gleiche schreiben? Das ist doch genau das was Du dem Rechner sagst, berechne `string_abw`, und dann schreibt der das 10 mal in die Datei. Wenn Du die Berechnung 10 mal machen willst dann muss die in der Schleife gemacht werden, beziehungsweise sollte in der Schleife die Funktion die Du nicht geschrieben hast 10 mal aufgerufen werden.
Das mit der Datei ist aber auch unnötig kompliziert – sammel die Ergebnisse einfach in einer Liste und berechne dann davon den Median. Es gibt recht wenig Gründe das mit Excel, selbst wenn man nicht sowieso schon `numpy` verwenden würde, was dafür alles mitbringt, gäbe es sogar in der Python-Standardbibliothek ein passendes Modul.
Bei `abw`/`string_abw` bist Du dann wieder von den guten Namen weg.
Auf Modulebene sollte eigentlich nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Hauptprogramm und Funktionsdefinitionen auf Modulebene zu vermischen ist so ziemlich das unübersichtlichste was man machen kann.
Edit: Die ``while``-Schleife sollte eine ``for``-Schleife sein. Du weisst ja vorher wie oft die durchlaufen wird.
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Samstag 24. August 2019, 13:53
von __blackjack__
Hier mal 9 Simulationen die auch grafisch dargestellt werden, ohne eine einzige Schleife in Python zu schreiben:
Code: Alles auswählen
#!/usr/bin/env python3
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
def main():
anzahl_punkte = 50_000
anzahl_simulationen = 9
anzahl_beobachtungen = anzahl_punkte * anzahl_simulationen
koordinaten = np.random.uniform(-1, 1, (2, anzahl_beobachtungen))
simulationsnummern = (
np.arange(anzahl_beobachtungen, dtype=int) // anzahl_punkte + 1
)
data = pd.DataFrame(
{
"Simulation": simulationsnummern,
"x": koordinaten[0],
"y": koordinaten[1],
}
)
data["im Kreis"] = data.x ** 2 + data.y ** 2 <= 1
print(data)
sns.set()
sns.set_style("white")
sns.relplot(
x="x",
y="y",
data=data,
col="Simulation",
col_wrap=3,
hue=data["im Kreis"].map({True: "ja", False: "nein"}),
height=2.5,
alpha=0.2,
edgecolor=None,
s=0.5,
)
sns.despine(left=True, bottom=True)
plt.savefig("test.png")
abweichungen = (
data[["Simulation", "im Kreis"]]
.groupby("Simulation")
.aggregate(lambda s: (4 * s["im Kreis"].sum() / s.count()) - np.pi)
.abs()
.rename(columns={"im Kreis": "Abweichung"})
)
print(abweichungen)
print("Median", abweichungen.median())
if __name__ == "__main__":
main()
Ausgabe:
Code: Alles auswählen
Simulation x y im Kreis
0 1 0.248617 -0.899030 True
1 1 0.583638 0.933873 False
2 1 -0.479969 -0.740391 True
3 1 -0.205841 0.750995 True
4 1 -0.569170 -0.763739 True
5 1 0.289227 0.986060 False
6 1 -0.850686 0.466077 True
7 1 -0.007428 0.822337 True
8 1 -0.314241 0.993074 False
9 1 -0.615237 0.744326 True
10 1 -0.595256 -0.310510 True
11 1 -0.743402 0.533695 True
12 1 0.167688 0.900862 True
13 1 0.185315 0.929584 True
14 1 0.737923 -0.711516 False
15 1 0.534371 -0.933298 False
16 1 0.153461 -0.413594 True
17 1 0.142533 -0.659727 True
18 1 -0.697535 0.464171 True
19 1 -0.869226 0.993673 False
20 1 -0.602461 -0.672275 True
21 1 0.724080 -0.071207 True
22 1 0.007867 -0.277731 True
23 1 -0.031231 -0.763030 True
24 1 0.562202 0.653644 True
25 1 0.303479 0.317006 True
26 1 0.636467 0.797304 False
27 1 -0.156960 0.141792 True
28 1 0.120300 -0.101982 True
29 1 0.473958 -0.547495 True
... ... ... ... ...
449970 9 -0.804482 -0.269954 True
449971 9 -0.343099 -0.631953 True
449972 9 0.641020 0.895462 False
449973 9 -0.601644 0.224732 True
449974 9 -0.011769 -0.737369 True
449975 9 -0.486407 0.003346 True
449976 9 -0.330856 0.480238 True
449977 9 0.357420 0.382098 True
449978 9 -0.562269 0.951690 False
449979 9 0.948544 -0.920091 False
449980 9 -0.900555 -0.301156 True
449981 9 0.268324 -0.052939 True
449982 9 -0.441177 -0.606367 True
449983 9 0.010240 -0.765957 True
449984 9 0.909817 -0.982228 False
449985 9 0.239209 -0.709239 True
449986 9 0.275994 0.709313 True
449987 9 -0.997069 0.647565 False
449988 9 0.579023 0.987883 False
449989 9 0.113928 -0.560803 True
449990 9 -0.502558 0.483353 True
449991 9 0.447500 0.912165 False
449992 9 -0.963741 -0.484180 False
449993 9 0.506204 -0.206595 True
449994 9 0.702868 0.673793 True
449995 9 -0.835202 -0.810745 False
449996 9 0.404636 -0.976605 False
449997 9 -0.069372 -0.650866 True
449998 9 -0.381711 -0.983373 False
449999 9 -0.921674 0.638572 False
[450000 rows x 4 columns]
Abweichung
Simulation
1 0.013033
2 0.006713
3 0.009113
4 0.004247
5 0.018647
6 0.000407
7 0.006793
8 0.002953
9 0.011047
Median Abweichung 0.006793
dtype: float64
Grafik:
Re: Script mehrfach ausführen und Median berechnen.
Verfasst: Samstag 24. August 2019, 16:14
von ThomasL
I like oder Daumen hoch!