2017-03-02 7 views
1

Ich versuche, mehr Daten zu den Matrizen hinzufügen, um zu analysieren und zu lösen, aber wie es derzeit die Brute-Operation durchführt, überschreitet es Python-Grenzen, wenn ich eine weitere Spalte zur Analyse hinzufügen. Gibt es eine Löser-Methode, die ein ähnliches Ergebnis liefert, anstatt sich durch Kombinationen zu schlagen? Die sample.csv ist ebenfalls unten aufgeführt. Danke für jeden Hinweis.Python, Solver-Methode oder Optimierung des aktuellen Codes?

import csv 
import itertools as it 
import numpy as np 

C = 2618.08 
B = 933.15 
A = 932.37 
adjust = 1 


D = csv.reader(open('sample.csv')) 

float_ABC = [] 
OUT = np.zeros((3, 9)) - 100 

for row in D: 
     float_ABC.append([str(x) for x in row]) 

float_ABC = float_ABC.astype(np.float) 

Alpha=float_ABC[:, [0,3,6,9,12,15]] 
Beta=float_ABC[:, [2,5,8,11,14,17]] 
Phi=float_ABC[:, [1,4,7,10,13,16]] 

plines1 = it.product(Alpha[0],Alpha[1],Alpha[2],Alpha[3], 
        Alpha[4],Alpha[5],Alpha[6],Alpha[7], 
        Alpha[8]) 

plines2 = it.product(Beta[0],Beta[1],Beta[2],Beta[3], 
        Beta[4],Beta[5],Beta[6],Beta[7], 
        Beta[8]) 

plines3 = it.product(Phi[0],Phi[1],Phi[2],Phi[3], 
        Phi[4],Phi[5],Phi[6],Phi[7], 
        Phi[8]) 


for count in range(0,6**9): 
    sumA = next(plines1) 
    sumB = next(plines2) 
    sumC = next(plines3) 

    if (sum(sumC)+B)/(sum(sumA)+C) <= (B+adjust)/(C) and \ 
     (sum(sumC)+B)/(sum(sumA)+C) >= (B+adjust-10)/(C) and \ 
     (sum(sumB)+A)/(sum(sumA)+C) > (sum(OUT[2])+A)/(sum(OUT[0])+C): 
     print("#",count,"- new option found!") 
     OUT = np.vstack((sumA,sumC,sumB)) 

und sample.csv:

13.4,-18.81,-24.75,5.82,-8.21,-10.8,0,0,0,3.3,1.56,2.05,-2.1,5.36,7.05,2.6,5.65,7.44 
0,-11.01,-14.49,0,-4.87,-6.41,0,0,0,0.6,2.24,2.95,1,4,5.26,1.7,2.73,3.59 
0,-40.74,-53.6,0,-17.86,-23.5,0,0,0,3.5,6.53,8.59,2.9,9.36,12.31,1.9,2.61,3.44 
1000,-1000,-1000,0,0,0,20.76,21.78,15.66,18.48,23.44,16.96,27.72,26.46,19.92,32.28,29.58,23.08 
1000,-1000,-1000,-2.28,-6.12,-4.16,-2.28,-2.53,-1.73,0,0,0,1.92,-1.85,-1.26,1.08,-1.27,-0.86 
1000,-1000,-1000,0,0,0,6.78,7.38,5.07,6.66,8.93,6.14,8.46,8.41,5.78,9.42,10.37,7.14 
1000,-1000,-1000,0,0,0,28.8,34.28,27.86,37.2,39.64,33.32,45.6,42.76,36.63,54,45.88,40.03 
1000,-1000,-1000,0,-4.95,-3.36,0,0,0,1.8,0.59,0.4,1.2,1.85,1.27,3.72,0.17,0.11 
1000,-1000,-1000,0,0,0,27.6,19.3,13.71,32.76,23.68,17.15,37.8,20.56,14.71,22.56,27.58,21.06 
+1

was meinst du mit „es überschreitet Pythons Grenzen“? Welche Art von Fehler bekommen Sie? Ich kann vorschlagen, 'für count, (sumA, sumB, sumC) in enumerate (zip (plines1, plines2, plines3)):' und Caching das Ergebnis von 'sum (sumA) + C' usw., da Sie es mehrmals neu berechnen jede Iteration. –

+1

Ich würde erwarten, dass der obige Code 'AttributeError: 'list' Objekt hat kein Attribut 'astype'' in der Zeile' float_ABC = float_ABC.astiype (np.float) 'seit' float_ABC' ist eine Liste ... –

+0

danke @ TadhgMcDonald-Jensen für die Eingabe - die Zeile 'für count, (SumA, SumB, SumC) in Enumerate (zip (plines1, plines2, plines3)):' aus irgendeinem Grund nicht in meinem Gehirn verbinden und ich hatte das verwendet in anderen Teilen meiner Analyse - das macht Sinn. Was die float_ABC-Zeile anbelangt, so hatte sie einige Einträge als Strings genommen und so alles in float-Objekte umgewandelt - scheint an meinem Ende gut zu funktionieren. Vielen Dank für die Hilfe aber! –

Antwort

0

Diese Antwort ist die Behandlung der Frage eher wie codereview dann mit Algorithmus zu helfen.

Zuerst kann man iterate over all three plines1 at the same time using zip

for sumA, sumB, sumC in zip(plines1, plines2, plines3): 
    pass 

aber dann eine laufende Zählung der Schritt zu bekommen Sie sind auf Sie enumerate verwenden können:

for count, (sumA, sumB, sumC) in enumerate(zip(plines1, plines2, plines3)): 
    pass 

auch ich bemerken Sie neu berechnen (B+adjust)/(C) und (B+adjust-10)/(C) jeder Iteration Wo beide in der Schleife überhaupt nicht geändert werden, so wird das Berechnen von ihnen einmal vor der Schleife statt jeder Iteration definitiv einige Ausführungszeit sparen:

high_check = (B+adjust)/(C) 
low_check = (B+adjust-10)/(C) 

for count, (sumA, sumB, sumC) in enumerate(zip(plines1, plines2, plines3)): 

    if (low_check <= (sum(sumC)+B)/(sum(sumA)+C) <= high_check 
      and <OTHER CHECK>): 
     ... 

als auch die Berechnung sum(sumA) (und für SUMB, SUMC) immer und immer wieder unecessarily teuer ist, und etwas verwirrend, da sumA ein Tupel von Werten darstellt, wäre es sinnvoll, die Summen einmal zu berechnen und nehmen die Tupel (sumA, sumB, sumC) als ein Wert genannt (2d Tupel nahe genug) matrix

for count, matrix in enumerate(zip(plines1, plines2, plines3)): 
    sumA, sumB, sumC = map(sum, matrix) 
    if (low_check <= (sumC+B)/(sumA+C) <= high_check 
      and <OTHER CHECK>): 
     ... 
     OUT = np.vstack(matrix) 

nur in ähnlicher Weise die Ausführungszeit nur (sum(OUT[2])+A)/(sum(OUT[0])+C) wenn OUT Änderungen neu berechnet werden reduzieren unveränderliche Werte neu berechnet werden benötigt:

OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

for ... in ...: 

    if ( ... 
      and (sumB+A)/(sumA+C) > OUT_check): 
     ... 
     OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

so Schnitt veränderten Code würde wie folgt aussehen:

plines1 = it.product(*Alpha) #star notation just unpacks all the elements into arguments 
plines2 = it.product(*Beta) 
plines3 = it.product(*Phi) 

high_check = (B+adjust)/(C) 
low_check = (B+adjust-10)/(C) 
OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 

for count, matrix in enumerate(zip(plines1, plines2, plines3)): 
    sumA, sumB, sumC = map(sum, matrix) 
    if (low_check <= (sumC+B)/(sumA+C) <= high_check 
      and (sumB+A)/(sumA+C) > OUT_check): 
     print("#",count,"- new option found!") 
     OUT = np.vstack(matrix) 
     OUT_check = (sum(OUT[2])+A)/(sum(OUT[0])+C) 
+0

Ich habe den Code geändert, um die Teile aufzulisten und zwischenzuspeichern, was bei der Berechnung des aktuellen Algorithmus einige Zeit spart. Mein Dank geht an die Optimierung des aktuellen Algorithmus. Ich nehme an, was ich für eine weitere Verbesserung der Zeit benötige - ist es, ob es einen Löseralgorithmus gibt, der die Zeit weiter verbessern kann, so dass ich weitere Datenspalten hinzufügen kann, um sie zu analysieren? Mein ultimatives Ziel ist es, dass die sample.csv 15 Elemente in jedes Tupel statt 9 importiert. Wäre es möglich, dies mit Hilfe eines Algorithmus von 'scipy' zu erreichen.optimieren, bevor Sie durch alle Pinien gehen? –

+0

Ich habe wirklich keine dieser Arten von Funktionen verwendet, so werde ich an dieser Front in der Lage zu helfen, nicht, sorry. –