2013-08-16 7 views
6

Pythonで(ループなしで)素早い方法で配列の再索引を割り当てることができます。 これは、使用して、所望の結果であるforループ:私はインデックスでaxを追加しようとすると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.]] 

Px,Py私は明らかに同じ結果を得ることはありません(3.3対3.1):

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

numpyでこれを行う方法はありますか?ありがとう。

+0

まず、私はグループが一緒に値でしょう、あなたはタプル(Pxを、Pyの)のリストを持っていることになります。このリストをソートするよりも、出現回数を数え、その数でxを掛けて配列に追加します。しかし、どういうわけかnumpyは二重エントリーをスキップするようです....奇妙な。 – Dschoni

答えて

7

はい、それは行うことができますが、それは少しトリッキーです:すべての

# 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、まったく同じ答えで私を4秒遅らせる。しかし、私はこれを行うより良い方法があることを心から望んでいました。 – Daniel

+0

ありがとう!フラットインデックスを取得するためにnp.ravel_multi_index関数を使用した方法が好きで、np.bincountをオプションのweightsパラメータとともに使用します。 – Paul

関連する問題