2015-06-07 9 views
5

Gibt es eine Möglichkeit, diese Schleife zu vermeiden, um den Code zu optimieren?NumPy: Wie man diese Schleife vermeidet?

import numpy as np 

cLoss = 0 
dist_ = np.array([0,1,0,1,1,0,0,1,1,0]) # just an example, longer in reality 
TLabels = np.array([-1,1,1,1,1,-1,-1,1,-1,-1]) # just an example, longer in reality 
t = float(dist_.size) 
for i in range(len(dist_)): 
    labels = TLabels[dist_ == dist_[i]] 
    cLoss+= 1 - TLabels[i]*(1. * np.sum(labels)/t) 
print cLoss 

Hinweis:dist_ und TLabels sind beide numpy Arrays mit der gleichen Form (t,1)

+3

Was versuchen Sie zu erreichen? –

+0

Nun, ich glaube, dass es korrekt ist, TLabels [dist_ == dist_ [i]] 'wird Werte von' TLabels' zurückgeben, die Indizes haben, wobei 'dist_ == dist_ [i] '. Zum Beispiel lasst 'dist_ = array ([2,1,2])' und 'TLabels = array ([1,2,3])' 'so' dist_ == dist_ [0] 'wird' array zurückgeben ([True, Falsch, Wahr]) 'als' TLabels [dist_ == dist_ [0]] = Array ([1,3]) ' – farhawa

+0

Nur um klar zu sein, sind die Arrays' (t, 1) 'oder' (t,) '? Wo wird 'cLoss' initialisiert? – hpaulj

Antwort

2

Ich bin mir nicht sicher, was Sie genau machen wollen, aber kennen Sie scipy.ndimage.measurements für die Berechnung auf Arrays mit Etiketten? Es sieht aus wie Sie wollen etwas wie:

cLoss = len(dist_) - sum(TLabels * scipy.ndimage.measurements.sum(TLabels,dist_,dist_)/len(dist_)) 
1

Ich bin nicht sicher, ob dies besser ist, da ich nicht genau verstehen, warum Sie vielleicht tun Dies. Viele Variablen in Ihrer Schleife sind zweiwertig und können daher im Voraus berechnet werden.

Auch die Einträge von dist_ können als boolesche Schalter verwendet werden, aber ich habe trotzdem eine explizite Kopie verwendet.

dist_  = np.array([0,1,0,1,1,0,0,1,1,0]) 
TLabels  = np.array([-1,1,1,1,1,-1,-1,1,-1,-1]) 
t   = len(dist) 
dist_zeros = dist_== 0 
one_zero_sum = [sum(TLabels[dist_zeros])/t , sum(TLabels[~dist_zeros])/t] 

cLoss  = sum([1-x*one_zero_sum[dist_[y]] for y,x in enumerate(TLabels)]) 

was ergibt cLoss = 8.2. Ich verwende Python3, also habe ich in Python2 nicht überprüft, ob es sich um eine echte Division handelt oder nicht.

2

Ich frage mich zuerst, was ist labels bei jedem Schritt in der Schleife?

Mit dist_ = array([2,1,2]) und TLabels=array([1,2,3])

ich

[-1 1] 
[1] 
[-1 1] 

Die unterschiedliche Länge sofort eine Warnung Fahne heben - es schwierig sein kann, dies vektorisieren.

Mit der längeren Arrays im editierten Beispiel

[-1 1 -1 -1 -1] 
[ 1 1 1 1 -1] 
[-1 1 -1 -1 -1] 
[ 1 1 1 1 -1] 
[ 1 1 1 1 -1] 
[-1 1 -1 -1 -1] 
[-1 1 -1 -1 -1] 
[ 1 1 1 1 -1] 
[ 1 1 1 1 -1] 
[-1 1 -1 -1 -1] 

Die labels Vektoren alle gleich lang sind. Ist das normal oder nur ein Zufall der Werte?

Tropfen ein paar Elemente aus der dist_ und labels sind:

In [375]: for i in range(len(dist_)): 
     labels = TLabels[dist_ == dist_[i]] 
     v = (1.*np.sum(labels)/t); v1 = 1-TLabels[i]*v 
     print(labels, v, TLabels[i], v1) 
     cLoss += v1 
    .....:  
(array([-1, 1, -1, -1]), -0.25, -1, 0.75) 
(array([1, 1, 1, 1]), 0.5, 1, 0.5) 
(array([-1, 1, -1, -1]), -0.25, 1, 1.25) 
(array([1, 1, 1, 1]), 0.5, 1, 0.5) 
(array([1, 1, 1, 1]), 0.5, 1, 0.5) 
(array([-1, 1, -1, -1]), -0.25, -1, 0.75) 
(array([-1, 1, -1, -1]), -0.25, -1, 0.75) 
(array([1, 1, 1, 1]), 0.5, 1, 0.5) 

Wieder unterschiedliche Längen von Etiketten, aber wirklich nur ein paar Berechnungen. Es gibt 1 v Wert für jeden anderen Wert.

Ohne alle Details auszuarbeiten, sieht es so aus, als ob Sie nur labels*labels für jeden einzelnen Wert berechnen und diese dann summieren.

Dies sieht wie ein groupBy Problem aus. Sie wollen die dist_ in Gruppen mit einem gemeinsamen Wert aufteilen und eine Funktion ihrer entsprechenden TLabels Werte addieren. Python itertools hat eine groupBy Funktion, so funktioniert pandas. Ich denke, beide erfordern Sie zu sortieren dist_.

Versuchen Sie, dist_ zu sortieren und sehen Sie, ob das dem Problem Klarheit verleiht.

Verwandte Themen