2016-03-24 6 views
0

Wie kann ich effizient von einem Array von im Wesentlichen Etiketten zu Gleichungen entsprechend diesen Bezeichnungen in Python 2.7 bewegen?Verschieben von einem Array von 'Etiketten' zu Array von Gleichungen entsprechend diesen Bezeichnungen in Python 2.7

Dieses Bild zeigt, was ich meine:

Die Gleichungen ziehen Werte von Array x, so "xn" in dem Bild in Python Bedingungen würden x [n] sein. Als ein Beispiel ist der 0. Eintrag in der Etikettenanordnung "a", was der Gleichung 1 + xn entspricht, die 1 + x [0] wäre. Der nächste ist "b", was x [1] * 2 ist.

Es gibt viele Möglichkeiten, dies zu erreichen, aber ich möchte mich auf Effizienz konzentrieren. Die tatsächlichen Arrays haben Tausende von Elementen, und diese Operation wird tausende Male ausgeführt (jeder Zeitschritt in meinem Modell). Das x-Array wird bei jedem Zeitschritt anders sein. Was ich eigentlich mache, ist, die Diagonalen für eine tridiagonale Matrix basierend auf verschiedenen Randbedingungen zu erstellen.

Kann mir jemand einen besseren Einblick geben, als jedes Mal mit einem Schaltergehäuse durch das gesamte Array zu iterieren? Hier

ist ein Beispiel für mich ist es eine Brute Art und Weise tun:

''' 
Equations corresponding to various labels 

a -> 2+x[n] 
b -> 3*x[n-1]+2x[n] 
c -> 4*x[n] 

These are just dummy equations I am making up for the example 
''' 

x = [4,7,6,6,9,12,4,9,1,11] 

labelArray = ['a','b','b','b','c','c','a','b','b','c'] 

outputArray = [] 
n = 0 
for label in labelArray: 
    if label == 'a': 
     output = 2+x[n] 
    elif label == 'b': 
     output = 3*x[n-1]+2*x[n] 
    elif label == 'c': 
     output = 4*x[n] 
    outputArray.append(output) 
    n += 1 

print outputArray 
# outputArray = [6, 26, 33, 30, 36, 48, 6, 30, 29, 44] 
+0

Wenn Sie sich über die Zeiteffizienz sprechen, denken Sie an die Nutzung von 'dict' – woozyking

Antwort

1

Hier ist eine Lösung, die ich kam mit. Es sollte schneller und prägnanter sein, obwohl es möglicherweise nicht die optimale Lösung ist.

from itertools import imap 

# List of values 
values = [4, 7, 6, 6, 9, 12, 4, 9, 1, 11] 

# A list of corresponding methods for each value, must be same length as values. 
# Optionally, you could create the data with the value and method in a tuple 
# e.g. [(4, 'a'), (7, 'b') ... (x, 'y')] 
# Though if you ensure both lists are of the same length, you can use the zip() 
# method, which does the same thing. 
methods = ['a', 'b', 'b', 'b', 'c', 'c', 'a', 'b', 'b', 'c'] 

# A dictionary with all your equations. You can also define them in a function 
# elsewhere and include them like 
# >{ 'a': external_function } 
equations = { 
    # Lambda is just an anonymous function. 
    'a': lambda index: 2 + values[index], 
    'b': lambda index: 3 * values[index-1] + 2 * values[index], 
    'c': lambda index: 4 * values[index], 
} 


# Returns an iterator to prevent eating up your memory with one big array. 
new_values = imap(lambda x,y: equations[x](y), methods, xrange(len(values))) 
print [value for value in new_values] 

Check out https://docs.python.org/2/library/functions.html für eine Erklärung der eingebauten Methoden hier verwende ich. Hier sind einige Informationen zu Iteratoren: http://anandology.com/python-practice-book/iterators.html

+0

ich beide Links überprüfen Sie zur Verfügung gestellt, aber ich sehe nicht,„imap“überall. Mein Code ist fehlerhaft, wenn ich versuche, dass "name 'imap' nicht definiert ist". Muss ich eine Bibliothek oder etwas importieren? Danke –

+0

Meine schlechte, ich habe vergessen, die Import-Anweisung hinzuzufügen. Fest! – BenHohner

+0

@TomStockman, irgendein Glück? – BenHohner

0

Hier haben Sie eine Version Ihres Codes, die ein Wörterbuch und eine Kartenfunktion verwendet. Ich hoffe es hilft dir.

functs = { 'a': '2+x[n]', 
      'b': '3*x[n-1] + 2*x[n]', 
      'c': '4*x[n]'} 

x = [4, 7, 6, 6, 9, 12, 4, 9, 1, 11] 

larray = ['a','b', 'b', 'b', 'c', 'c', 'a', 'b', 'b', 'c'] 

result = list(map(lambda n: eval(functs[larray[n]]), xrange(len(larray)))) 

print result 

# result = [6, 26, 33, 30, 36, 48, 6, 30, 29, 44] 
+0

Dies ist eine interessante Lösung, aber tatsächlich ungefähr 20x langsamer als mein ursprünglicher Code, zumindest auf meinem Computer. Danke für deine Hilfe. –

+0

@Tom Stockman: Sie können 'import iertools' hinzufügen und' itertools.imap (...) 'anstelle von' imap (...) 'in BenHohners Lösung verwenden. Es ist so schnell wie Ihre Lösung. – guerreiro