12

合計する必要のある値の配列があると仮定します

d = [1,1,1,1,1]

合計する必要のある要素を指定する2番目の配列

i = [0,0,1,2,2]

結果は、サイズの新しい配列に格納されますmax(i)+1。したがって、たとえばi=[0,0,0,0,0]、のすべての要素を合計し、サイズの新しい配列のd位置に結果を格納することと同じです。01

私はこれを使用して実装しようとしました

c = zeros(max(i)+1)
c[i] += d

ただし、この+=操作では各要素が1回だけ追加されるため、予期しない結果が得られます。

[1,1,1]

それ以外の

[2,1,2]

この種の合計をどのように正しく実装しますか?

4

5 に答える 5

13

質問を正しく理解していれば、これには高速な関数があります(データ配列が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は、一部のカウントがゼロの場合でも、すべての整数range(max(i))の配列を返します。

于 2010-09-11T01:00:49.720 に答える
3

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))
于 2014-06-17T10:36:15.057 に答える
2
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
于 2010-08-31T04:53:55.807 に答える
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.]
于 2010-09-02T15:42:08.897 に答える
0

ラベルで部分行列を合計する一般的なケースでは、次のコードを使用できます

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

最初の方法は、スパース行列の乗算を使用します。2つ目は、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
于 2015-06-02T10:40:32.823 に答える