2016-04-26 8 views
2

Ich versuche, +1 auf einige spezifische Zellen eines numpy Array zusammenzufassen, aber ich kann nicht jede mögliche Weise, ohne langsame Schleifen finden:Accumulate konstanten Wert in Numpy Array

coords = np.array([[1,2],[1,2],[1,2],[0,0]]) 
X  = np.zeros((3,3)) 

for i,j in coords: 
    X[i,j] +=1 

Resultat:

X = [[ 1. 0. 0.] 
    [ 0. 0. 3.] 
    [ 0. 0. 0.]] 

X[coords[:,0],coords[:,1] += 1 kehrt

X = [[ 1. 0. 0.] 
    [ 0. 0. 1.] 
    [ 0. 0. 0.]] 

Jede Hilfe?

Antwort

3

numpy.at ist genau für diese Situationen.

In [1]: np.add.at(X,tuple(coords.T),1) 

In [2]: X 
Out[2]: 
array([[ 1., 0., 0.], 
     [ 0., 0., 3.], 
     [ 0., 0., 0.]]) 
3

können Sie np.bincount verwenden, wie so -

out_shape = (3,3) # Input param 

# Get linear indices corresponding to coords with the output array shape. 
# These form the IDs for accumulation in the next step. 
ids = np.ravel_multi_index(coords.T,out_shape) 

# Use bincount to get 1-weighted accumulations. Since bincount assumes 1D 
# array, we need to do reshaping before and after for desired output. 
out = np.bincount(ids,minlength=np.prod(out_shape)).reshape(out_shape) 

Wenn Sie als 1s andere Werte zuweisen versuchen, Sie die zusätzliche Eingabeargument verwenden können, in Gewichte np.bincount zu füttern.

Probelauf -

In [2]: coords 
Out[2]: 
array([[1, 2], 
     [1, 2], 
     [1, 2], 
     [0, 0]]) 

In [3]: out_shape = (3,3) # Input param 
    ...: ids = np.ravel_multi_index(coords.T,out_shape) 
    ...: out = np.bincount(ids,minlength=np.prod(out_shape)).reshape(out_shape) 
    ...: 

In [4]: out 
Out[4]: 
array([[1, 0, 0], 
     [0, 0, 3], 
     [0, 0, 0]], dtype=int64) 
+0

Danke, ich habe nicht darüber nachgedacht. Ich erwartete, dass numpy eine viel einfachere Lösung für solch eine triviale Operation zur Verfügung stellen würde. – memecs

+2

@memecs: IMHO trivial oder nicht, ich glaube nicht, dass es * das * üblich ist, und das ist es, was zählt, wenn einfachere Problemlösungen implementiert werden. ;-) – Peque

2

Eine weitere Option ist np.histogramdd:

bins = [np.arange(d + 1) for d in X.shape] 
out, edges = np.histogramdd(coords, bins) 

print(out) 
# [[ 1. 0. 0.] 
# [ 0. 0. 3.] 
# [ 0. 0. 0.]]