2016-04-19 11 views
-1

Ich denke, dass es ein sehr subtiles Problem ist, vielleicht ein unbekannter Fehler in Python2.7. Ich mache eine interaktive Anwendung. Es sollte das WLS-Modell (Weighted Linear Regression) an die Punktwolke anpassen. Zu Beginn liest das Skript die Daten aus einer Textdatei (nur eine einfache Tabelle mit Indizes, Werten und Fehlern jedes Punktes). Aber in den Daten könnten einige Punkte mit Nullwert durch nocompl=99.9999 markiert sein. Ich muss wissen, was diese Punkte sind, um sie abzulehnen, bevor das Skript die Anpassung beginnt. Ich mache das auf folgende Weise:Gibt es einen Unterschied zwischen Zip zwei und mehr als zwei Listen?

# read the data from input file 
Bunchlst = [Bunch(val1 = D[:,i], err_val1 = D[:,i+1], val2 = D[:,i+2], err_val2 = D[:,i+3]) for i in range(1, D.shape[1] - 1, 4)] 

# here is the problem 
for b in Bunchlst: 
    b.compl = list(np.logical_not([1 if nocompl in [im,ie,sm,se] else 0 for v1,e1,v2,e2 in zip(b.val1,b.err_val1,b.val2,b.err_val2)])) 

# fit the model to the "good" points 
wls = sm.WLS(list(compress(b.val1,b.compl)), sm.add_constant(list(compress(b.val2,b.compl)), prepend=False), weights=[1.0/i for i in list(compress(b.err_val2,b.compl))]).fit() 

WLS model implemented in Python. compress() ermöglicht das Filtern der Daten (NULL-Werte weglassen). Aber dieser Fall erzeugt den Fehler:

wls = sm.WLS(...).fit() AttributeError: 'numpy.float64' object has no attribute 'WLS'

ich eine Untersuchung gemacht, und wenn ich nur zwei Listen zip, das Problem verschwindet und WLS-Modell berechnet sich richtig:

for b in Bunchlst: 
    b.compl = list(np.logical_not([1 if nocompl in [v1,v2] else 0 for v1,v2 in zip(b.val1,b.val2)])) 

schrieb ich, dass wahrscheinlich kann es ein Fehler sein, weil ich in beiden Fällen b.compl überprüft habe. Immer gab es die gleichen Listen mit True oder False Werten (abhängig von den Daten aus der Eingabedatei). Darüber hinaus führen einfache Überlegungen dass es für viele Listen arbeiten:

>>> K = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 
>>> L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> M = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30] 
>>> N = [32, 33, 34, 35, 36, 37, 38, 39, 40, 32] 

>>> [1 if 26 in [k,l,m,n] else 0 for k,l,m,n in zip(K,L,M,N)] 
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0] 

Alles Gute,

Benek

+0

Wo setzen Sie die Variablen für den 'nocompl in [im, dh, sm, se]' Test in Ihrem Listenverständnis? Die 'for'-Schleife setzt verschiedene Namen: 'für v1, e1, v2, e2 in' –

+0

Auf jeden Fall teilen Listenkomprehensionen in Python 2 alle lokalen Namen mit dem aktuellen Bereich, also wenn Sie' for im verwenden, dh sm, se in 'in the loop, dann wird' sm' gesetzt und stört den Import. –

+0

Ähm, es tut mir leid. Ich schrieb nur die wichtigsten Teile meines Codes um und um meinen Code lesbarer zu machen, änderte ich die Namen von Variablen wie 'im',' ie', 'sm',' se' für 'v1',' e1' und so weiter aber nicht überall. Dadurch hat @MartijnPieters einen Grund für mein Problem gefunden. Jetzt funktioniert der Code korrekt. Vielen Dank! – Benek

Antwort

1

Nein, es gibt keinen Unterschied, wie zip() mit 2 oder mehr Listen arbeitet . Stattdessen wird Ihr Listenverständnis dem Namen sm in der Schleife zugewiesen, während Sie gleichzeitig den Namen sm verwenden, um auf das Modul statsmodels zu verweisen.

Ihre einfachere Version mit zwei Listen tut dies nicht, daher wird der Name sm nicht wiederhergestellt, und Sie stoßen nicht auf das Problem. Teil des lokalen Bereich

In Python 2 in der Liste Verständnis verwendeten Namen sind:

>>> foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'foo' is not defined 
>>> [foo for foo in 'bar'] 
['b', 'a', 'r'] 
>>> foo 
'r' 

Hier wird der Name foo wurde in der for Schleife der Liste Verständnis gesetzt, und der Name ist noch verfügbar, nachdem die Schleife.

Benennen Sie entweder Ihren Import um oder benennen Sie Ihre Loop-Variablen um.

Verwandte Themen