インデックスでnumpyの配列の累積合計
質問
あなたが一緒に加算される必要があります値の配列を持っていると仮定します。
d = [1,1,1,1,1]
と要素が一緒に加算される必要がある二番目の配列の指定
i = [0,0,1,2,2]
結果は、サイズmax(i)+1
の新しい配列に格納されます。そう例えばi=[0,0,0,0,0]
はd
のすべての要素を合計し、サイズ0
の新しいアレイの位置1
に結果を記憶することに等価であろう。
私はこの使用して
を実装してみましたc = zeros(max(i)+1)
c[i] += d
はしかし、+=
動作はこうしての予期せぬ結果を与え、一度だけ各要素を追加
[1,1,1]
の代わりに
[2,1,2]
どのようにして正しく合計?
のこの種を実装します解決
この溶液は、(それが代わりi
の個々のエントリの可能な指標値にわたって反復処理)大きな配列のために、より効率的であるべきである。
import numpy as np
i = np.array([0,0,1,2,2])
d = np.array([0,1,2,3,4])
i_max = i.max()
c = np.empty(i_max+1)
for j in range(i_max+1):
c[j] = d[i==j].sum()
print c
[1. 2. 7.]
他のヒント
私が正しく質問を理解していれば、このための高速な関数は(長いデータ配列は1Dであるとされる)がある。
>>> i = np.array([0,0,1,2,2])
>>> d = np.array([0,1,2,3,4])
>>> np.bincount(i, weights=d)
array([ 1., 2., 7.])
すべての整数のnp.bincount戻っ配列は、範囲(最大値(i))を、いくつかのカウントがゼロ
であっても、Juh_さんのコメントには、最も効率的なソリューションです。ここでの作業コード:
import numpy as np
import scipy.ndimage as ni
i = np.array([0,0,1,2,2])
d = np.array([0,1,2,3,4])
n_indices = i.max() + 1
print ni.sum(d, i, np.arange(n_indices))
def zeros(ilen):
r = []
for i in range(0,ilen):
r.append(0)
i_list = [0,0,1,2,2]
d = [1,1,1,1,1]
result = zeros(max(i_list)+1)
for index in i_list:
result[index]+=d[index]
print result
あなたがラベルで部分行列を合計したいときは、次のコードをを使用することができます一般的なケースでは、
import numpy as np
from scipy.sparse import coo_matrix
def labeled_sum1(x, labels):
P = coo_matrix((np.ones(x.shape[0]), (labels, np.arange(len(labels)))))
res = P.dot(x.reshape((x.shape[0], np.prod(x.shape[1:]))))
return res.reshape((res.shape[0],) + x.shape[1:])
def labeled_sum2(x, labels):
res = np.empty((np.max(labels) + 1,) + x.shape[1:], x.dtype)
for i in np.ndindex(x.shape[1:]):
res[(...,)+i] = np.bincount(labels, x[(...,)+i])
return res
第一の方法は、疎行列乗算を使用します。もう一つはuser333700の答えを一般化したものです。どちらの方法でも、同等のスピードを持っています:
x = np.random.randn(100000, 10, 10)
labels = np.random.randint(0, 1000, 100000)
%time res1 = labeled_sum1(x, labels)
%time res2 = labeled_sum2(x, labels)
np.all(res1 == res2)
出力:
Wall time: 73.2 ms
Wall time: 68.9 ms
True
所属していません StackOverflow