Erstes Element aus Array[Arrays]

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
JeanC
User
Beiträge: 11
Registriert: Dienstag 29. Dezember 2015, 18:46

Programmiere erst seit einigen Tagen in Python (vorher Ruby), sodass ich bitte eventuell falsches Wording (aus Ruby) zu verzeihen.

Das Problem ist im Quellcode der Methode plot() beschrieben:

Code: Alles auswählen

import numpy as np
from scipy.stats import lognorm
import matplotlib.pyplot as plt


# Eigene Klasse definieren, um die Parameter zu kapseln
class LogNormal:
    def __init__(self, mu, sigma):
        self.mu = mu
        self.sigma = sigma

    def pdf(self, x):
        return lognorm.pdf(x, self.sigma, self.mu)

    def cdf(self, x):
        return lognorm.cdf(x, self.sigma, self.mu)

    def ppf(self, p):
        return lognorm.ppf(p, self.sigma, self.mu)

    def data(self, intervals=100):
        # Bestimmen der x-Werte
        x = np.linspace(self.ppf(0.0001),
                        self.ppf(0.9999),
                        intervals)

        # Bestimmen der PDF- wie auch CDF-Werte
        y_pdf = self.pdf(x)
        y_cdf = self.cdf(x)

        # Alles in ein Array [x, pdf(x), cdf(x)] packen
        d = []
        for i in range(len(x)):
            d.append([x[i], y_pdf[i], y_cdf[i]])

        return d

    def plot(self, intervals=100):
        d = self.data(intervals)
 
        # Hier müsste nun wieder aus d ein Arrays füx x, y_pdf und cdf_extrahiert werden
        # Gibt es eine Methode in Python, der ich sagen kann
        # x = d.Erstes_Element_Arrays
        # y_pdf = d.Zweites_Element_Arrays
        # y_cdf = d.Drittes_Element_Arrays
 
        # Zeichnen des Graphen
        plt.figure(1)
        plt.subplot(211)
        plt.grid(True)
        plt.xlim(0, 3)
        plt.plot(x, y_pdf, 'b-')

        plt.subplot(212)
        plt.grid(True)
        plt.xlim(0, 3)
        plt.plot(x, y_cdf, 'b-')       

# Instanz der Klasse erzeugen
dist = LogNormal(mu=0.0, sigma=0.25)
dist.data()
dist.plot()
Ich wüsste, wie ich x, y_pdf und y_cdf aus d extrahieren kann, jedoch würde mch interessieren, ob es dafür bereits fertige Methoden gibt.

Generell bin ich auch mit der momentanen Codelogik nicht zufrieden. Erst ein Array d [x, y_pdf, y_cdf] aus seinen Bestandteilen erstellen, um es dann in einem anderen Teil des Codes wieder in die Bestandteile zu zerlegen. Ich dachte mir, dass die Methode data/b] alle daten kapseln sollte. Eventuell macht es auch mehr Sinn, drei Array zurückzugeben, eins für x, eins für y_pdf und eins für y-cdf. Bin für alle Vorschläge dankbar!
Zuletzt geändert von JeanC am Donnerstag 31. Dezember 2015, 22:10, insgesamt 1-mal geändert.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Das Stichwort ist Iterable Unpacking.

Code: Alles auswählen

foo, bar, baz = [1, 2, 3]
JeanC
User
Beiträge: 11
Registriert: Dienstag 29. Dezember 2015, 18:46

Super, es geht also mit

Code: Alles auswählen

x = tuple(i[0] for i in d)
y_pdf = tuple(i[1] for i in d)
y_cdf = tuple(i[2] for i in d)
Der Code sieht nun wie folgt aus:

Code: Alles auswählen

import numpy as np
from scipy.stats import lognorm
import matplotlib.pyplot as plt

# Eigene Klasse definieren, um die Parameter zu kapseln
class LogNormal:
    def __init__(self, mu, sigma):
        self.mu = mu
        self.sigma = sigma

    def pdf(self, x):
        return lognorm.pdf(x, self.sigma, self.mu)

    def cdf(self, x):
        return lognorm.cdf(x, self.sigma, self.mu)

    def ppf(self, p):
        return lognorm.ppf(p, self.sigma, self.mu)

    def data(self, intervals=100):
        # Bestimmen der x-Werte
        x = np.linspace(self.ppf(0.0001),
                        self.ppf(0.9999),
                        intervals)

        # Bestimmen der PDF- wie auch CDF-Werte
        y_pdf = self.pdf(x)
        y_cdf = self.cdf(x)

        # Alles in ein Array [x, pdf(x), cdf(x)] packen
        d = []
        for i in range(len(x)):
            d.append([x[i], y_pdf[i], y_cdf[i]])
        return d

    def plot(self, intervals = 100):

        # Datenpunkte ermitteln
        d = self.data(intervals)

        # Datenpunkte aufspalten
        x = tuple(i[0] for i in d)
        y_pdf = tuple(i[1] for i in d)
        y_cdf = tuple(i[2] for i in d)

        # Zeichnen des Graphen
        plt.figure(1)
        plt.subplot(211)
        plt.grid(True)
        plt.xlim(0, 3)
        plt.plot(x, y_pdf, 'b-')

        plt.subplot(212)
        plt.grid(True)
        plt.xlim(0, 3)
        plt.plot(x, y_cdf, 'b-')

        plt.show()

# Instanz der Klasse erzeugen
dist = LogNormal(mu=0.0, sigma=0.25)
dist.plot()
Hat jemand noch Ideen, was an dem Ansatz noch ungünstig ist?
Zuletzt geändert von JeanC am Donnerstag 31. Dezember 2015, 22:30, insgesamt 1-mal geändert.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ah, da hätte ich genauer lesen sollen.

Code: Alles auswählen

>>> a, b, c = zip(*[
...     [1, 2, 3],
...     [4, 5, 6],
...     [7, 8, 9]
... ])
>>> a
(1, 4, 7)
>>> b
(2, 5, 8)
>>> c
(3, 6, 9)
JeanC
User
Beiträge: 11
Registriert: Dienstag 29. Dezember 2015, 18:46

Sorry, hatte deinen Vorschlag aufgegriffen und mittels Google kam ich zu der angegebenen Lösung. Hatte dementsprechend meinen Beitrag editiert, da ich dachte, ich wäre der einzige, der an einem Silversterband nicht feiert. :-)

Aber deine Lösung mit zip(*..) ist viel eleganter. Merci!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@JeanC: Du verwendest numpy, also benutze es auch

Code: Alles auswählen

#
    def generate_data(self, intervals=100):
        # Bestimmen der x-Werte
        x = np.linspace(self.ppf(0.0001), self.ppf(0.9999), intervals)

        # Bestimmen der PDF- wie auch CDF-Werte
        y_pdf = self.pdf(x)
        y_cdf = self.cdf(x)

        # Alles in ein Array [x, pdf(x), cdf(x)] packen
        return np.vstack([x, y_pdf, y_cdf])

    def plot(self, intervals=100):

        # Datenpunkte ermitteln
        data = self.generate_data(intervals)

        # Datenpunkte aufspalten
        x, y_pdf, y_cdf = data
        [...]
JeanC
User
Beiträge: 11
Registriert: Dienstag 29. Dezember 2015, 18:46

Merci für die tollen Hinweise. Python ist wahrlich so mächtig, dass ich nun vor der gewaltigen Aufgabe stehe, die Möglichkeiten der einzelnen Module zu erforschen. Auch hier gilt wohl: Man wächst mit den Aufgaben. :-)
Antworten