2013-08-16 4 views
6

Ich möchte einen schnellen Weg (ohne for-Schleife) in Python finden, um reoccuring Indizes eines Arrays zuzuordnen. Diese ist das gewünschte Ergebnis mit einer for-Schleife:Identifizieren von identischen Array-Indizes in Python/Numpy

import numpy as np 
a=np.arange(9, dtype=np.float64).reshape((3,3)) 
# The array indices: [2,3,4] are identical. 
Px = np.uint64(np.array([0,1,1,1,2])) 
Py = np.uint64(np.array([0,0,0,0,0])) 
# The array to be added at the array indices (may also contain random numbers). 
x = np.array([.1,.1,.1,.1,.1]) 

for m in np.arange(len(x)): 
    a[Px[m]][Py[m]] += x 

print a 
%[[ 0.1 1. 2.] 
%[ 3.3 4. 5.] 
%[ 6.1 7. 8.]] 

Wenn ich versuche, x-a bei den Indizes hinzufügen Px,Py ich natürlich nicht bekommen das gleiche Ergebnis (3,3 vs. 3,1):

a[Px,Py] += x 
print a 
%[[ 0.1 1. 2.] 
%[ 3.1 4. 5.] 
%[ 6.1 7. 8.]] 

Gibt es eine Möglichkeit, dies mit numpy zu tun? Vielen Dank.

+0

Zunächst einmal würde ich die Werte zusammen Gruppe, so dass Sie eine Liste von Tupeln (Px, Py) haben. Dann sortiere diese Liste, zähle die Vorkommen, multipliziere x mit dieser Zahl und füge das Array hinzu. Aber irgendwie scheint numpy doppelte Einträge zu überspringen ... seltsam. – Dschoni

Antwort

7

Ja, es kann getan werden, aber es ist ein wenig kompliziert:

# convert yourmulti-dim indices to flat indices 
flat_idx = np.ravel_multi_index((Px, Py), dims=a.shape) 
# extract the unique indices and their position 
unique_idx, idx_idx = np.unique(flat_idx, return_inverse=True) 
# Aggregate the repeated indices 
deltas = np.bincount(idx_idx, weights=x) 
# Sum them to your array 
a.flat[unique_idx] += deltas 
+0

Bah, schlag mich mit der exakt gleichen Antwort um 4 Sekunden. Obwohl ich aufrichtig gehofft hatte, dass es einen besseren Weg dafür gab. – Daniel

+0

Danke! Ich mag die Art und Weise, wie Sie die Funktion np.ravel_multi_index verwendet haben, um die flachen Indizes zu erhalten, und dann np.bincount mit dem optionalen Parameter wholesales verwenden. – Paul