You can use np.bincount, like so -
id = ind_x*3 + ind_y # Generate 1D linear index IDs for use with bincount
box_sum = np.bincount(id,values,minlength=9).reshape(3,3)
box_nb = np.bincount(id,minlength=9).reshape(3,3)
Sample run -
1) Setup inputs and run original code :
In [59]: # Let's use random numbers to test out variety as also OP states :
# ".. in the application it may be random values"
...: values = np.random.randint(0,1000,(1000))
...:
...: # Rest of the code same as the one posted within the question
...: ind_x = (values/10)%3
...: ind_y = values%3
...:
...: box_sum = np.zeros((3,3))
...: box_nb = np.zeros((3,3))
...:
...: for v in range(0,len(values)):
...: box_sum[ind_x[v],ind_y[v]] += values[v]
...: box_nb[ind_x[v],ind_y[v]] += 1
...:
In [60]: box_sum
Out[60]:
array([[ 64875., 50268., 50496.],
[ 48759., 61661., 53575.],
[ 53076., 48529., 76576.]])
In [61]: box_nb
Out[61]:
array([[ 125., 105., 96.],
[ 97., 116., 116.],
[ 96., 100., 149.]])
2) Use proposed approach and thus verify results :
In [62]: id = ind_x*3 + ind_y
In [63]: np.bincount(id,values,minlength=9).reshape(3,3)
Out[63]:
array([[ 64875., 50268., 50496.],
[ 48759., 61661., 53575.],
[ 53076., 48529., 76576.]])
In [64]: np.bincount(id,minlength=9).reshape(3,3)
Out[64]:
array([[125, 105, 96],
[ 97, 116, 116],
[ 96, 100, 149]])