2017-10-23 4 views
0

Mein Projekt hat nur einen Fehler fangen, ich möchte folgendes tun:wie man element-wise operator (subtract) in numpy fancy index (mehr als ein selbe index in der index-liste) macht?

import numpy as np 
a = np.array([1,2,3,4]) 
b = np.array([5,6,7,8]) 
a[[0,1,1]] -= b[[0,1,2]] 

Ich hoffe, das Ergebnis zweiten a[1] = a[1]-b[1]-b[2] = -11, weil es zwei Index = 1 in a [xxx], so dass ich eine wollen [1 ] subtrahiere zweimal. Aber dieser numpy Code nur produzieren:

array([-4, -4, -5]) 

Aus dem Grund möchte ich numpy meine Algorithmus Geschwindigkeit steigern, also nur ich vectorize numpy Code (vermeiden Python for-Schleife)

+0

Was ist die erwartete Ausgabe? – Divakar

+0

'a [1] - = b [[1,2]]. Sum()' – BlackBear

+0

angenommen c = a [[1,2,2,3]] - b [[1,2,3,4]] , Ich möchte c [1] = a [2] -b [2], c [2] = a [2] -b [2] -b [3] – machen

Antwort

1

Ansatz # 1 schreiben wollen

Sie müssen bei bestimmten Indizes mit gegebenen Werten np.subtract.at für diejenigen akkumulierten Subtraktion verwenden -

np.subtract.at(a,[0,1,1], b[[0,1,2]]) 

Probelauf -

In [8]: a = np.array([1,2,3,4]) 

In [9]: b = np.array([5,6,7,8]) 

In [10]: np.subtract.at(a,[0,1,1], b[[0,1,2]]) 

In [11]: a 
Out[11]: array([ -4, -11, 3, 4]) 

Ansatz # 2

Alternativ mit np.bincount -

ind = np.array([0,1,1]) 
val = b[[0,1,2]] 
unq_ind = np.unique(ind) 
a[unq_ind] -= np.bincount(ind, val).astype(a.dtype) 

Wenn ind bereits sortiert ist, erhalten unq_ind, wie so -

unq_ind = ind[np.concatenate(([True],ind[1:] != ind[:-1]))] 

Ansatz # 2S (Simpler)

Wenn Sie nicht um mit der unique Arbeit zu verwirren wollen, verwenden Sie minlength arg mit bincount -

a -= np.bincount([0,1,1], b[[0,1,2]], minlength=a.size).astype(a.dtype) 

Für akkumulierte Ergänzungen

Um die vorgeschlagenen Ansätze zum Hinzufügen statt Subtrahieren zu verwenden, ersetzen Sie einfach np.subtract.at mit np.add.at und für die bincount Methoden ersetzen Sie -= durch +=.

+0

Vielen Dank, Sie sind ein numpiger Experte, dies Fehler ist wirklich schwer zu finden, ich habe fast den ganzen Nachmittag genommen, um es herauszufinden. – machen

+0

@machen Nicht gerade ein Fehler. Mit 'a [[0,1,1]] - = b [[0,1,2]]' wird es nicht akkumuliert und subtrahiert, wie es für Ihre Anwendung vorgesehen ist. Aber ich mache dir keine Vorwürfe, vielleicht hätte es eine Warnung auslösen können, um fair zu sein. – Divakar

+0

Ja, vielleicht ist es das vom Designer gewünschte Verhalten, aber nicht mein Algorithmus. – machen