2016-04-01 8 views
2

Ich versuche eine Funktion zu zeichnen, die bedingt definiert ist. Im Einzelnen: U (x) = (2 ** delta)/((Dd) ** delta) * (D/2 - (x-x0)) ** delta, für abs (x-x0) kleiner als D/2 und 0 sonst.Bedingtes Plotten mit Numpy und Pyplot

Aber mein Problem ist, dass ich x, x0 als numpy Arrays haben möchte, weil dies ist, wie ich sie im Rest meines tatsächlichen Codes verwende.

ich Set-up das folgende Beispiel:

import numpy as np 
import matplotlib.pyplot as plt 
AD = 0.2 
D = 0.4 
delta = 8 

def Parabolic(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    if tempx<tempD: 
     return ((2**delta)/(D-AD)**delta)*(D/2 - (x-x0))**delta 
    else: 
     return 0 

figure = plt.figure(figsize=(10,8), dpi=72) 
xmin = -1.0 
xmax = 1.0 
X = np.linspace(xmin,xmax,1000) 
plt.plot(X, Parabolic(X, delta=8, D=0.4, AD=0.2)) 

Offensichtlich dieses Beispiel funktioniert nicht, da die Linie tempx<tempD die Fehler auslöst, dass ein Wahrheitswert einer Liste nicht eindeutig ist.

Ich suchte in der Dokumentation von numpy und fand die Funktion np.less (tempx, tempD). Aber wenn ich tempx < tempD durch np.less(tempx, tempD) ersetze, funktioniert es immer noch nicht, da ich wieder nach einem Wahrheitswert einer ganzen Liste frage. Ich verstehe, dass das Problem nicht mit numpy ist, aber mit meiner Unfähigkeit zu verstehen, wie man die logischen Funktionen verwendet, die numpy zur Verfügung stellt.

Es tut mir leid, wenn diese einen Weg in einem anderen Beitrag geantwortet haben, habe ich in diesem Forum gesucht, konnte aber nichts anderes als die curve() Methode finden. Ich möchte jedoch mein numpy.array-Format für die Verwendung in meinen tatsächlichen Codes beibehalten. Ich würde wetten, dass die Antwort sehr einfach sein muss, ich kann einfach nicht daran denken.

+0

Auf dem Fehler finden Sie unter http: // stackoverflow.com/a/30081652/901925 und seine Sidebar. – hpaulj

Antwort

3

das Versuchen, die verwendet numpy logische Arrays:

import numpy as np 
import matplotlib.pyplot as plt 
AD = 0.2 
D = 0.4 
delta = 8 

def Parabolic(x, delta, D, AD): 
    rtn_arr = np.zeros(len(x)) 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    lgc_arr = tempx<tempD 
    x_cut = x[lgc_arr] 
    x0_cut = x0[lgc_arr] 
    rtn_arr[lgc_arr] = ((2**delta)/(D-AD)**delta)*(D/2 - (x_cut-x0_cut))**delta 
    return rtn_arr 

figure = plt.figure(figsize=(10,8), dpi=72) 
xmin = -1.0 
xmax = 1.0 
X = np.linspace(xmin,xmax,1000) 
plt.plot(X, Parabolic(X, delta=8, D=0.4, AD=0.2)) 
+0

Nun, genau das habe ich gesucht. Ich konnte mein Problem mit Python-Listen lösen und anhängen, aber natürlich war es nicht so gut. Deines war was ich suchte. Ich wusste nicht, dass man 'x_cut = x [lgc_array]' verwenden könnte, um nur die Elemente zu erhalten, die wahr entsprechen! Eine letzte Sache: Könnten Sie mir erklären, wie die Zeile 'lgc_arr = tempx

+0

'tempx hpaulj

+0

@GeorgeDatseris Genau wie du sagst. Die Nummernfelder definieren die Bedingungsoperatoren neu (was für jede benutzerdefinierte Klasse getan werden kann https://docs.python.org/2/library/stdtypes.html), so dass die Verwendung von '>, <' usw. in numpy-Arrays numpy Arrays zurückgibt . Dann ist 'tempx Xirtaminu

2

Parabolic muss ein ufunc sein, so dass Sie nicht Python-Test in Ihrem Code setzen.

eine einfache Abhilfe ist:

def Parabolic(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    u=(((2**delta)/(D-AD)**delta)*(D/2 - (x-x0))**delta) 
    u[tempx>=tempD]=0 
    return u 

oder unnötige Berechnungen zu vermeiden:

def Parabolic2(x, delta, D, AD): 
    x0 = np.round(x) 
    tempx = np.abs(x-x0) 
    tempD = D/2*np.ones(len(x)) 
    u= zeros_like(x) 
    valid=tempx<tempD 
    u[valid]=(((2**delta)/(D-AD)**delta)*(D/2 - (x-x0)[valid])**delta) 
    return u 

Die zweite ist slighty schneller:

In [141]: %timeit Parabolic(x,8,.4,.2) 
1000 loops, best of 3: 310 µs per loop 

In [142]: %timeit Parabolic2(x,8,.4,.2) 
1000 loops, best of 3: 218 µs per loop 
+0

Dies ist auch eine schöne Problemumgehung und ziemlich einfach Code-weise. Es bedeutet jedoch, dass ich die Funktion für alle Werte, kleine und große, berechnen muss. Und das wird im normalen Code viel Zeit in Anspruch nehmen. Ich beabsichtige, die erste Antwort sowohl für sehr hohe als auch für sehr kleine Werte der "u" -Funktion zu verwenden, hauptsächlich um Berechnungen zu vermeiden. –

+0

ok; Ich füge einen anderen Weg in diesem Fall hinzu. –

+0

Ich glaube nicht, dass die zweite Version funktionieren wird, da die Länge von u [tempx Xirtaminu