I\'m using numpy and am trying to figure out an issue I\'m having with matrices. Say I have a 3 x 3 matrix and want to transform it into a 2 x 2 matrix through summing the first
You can do this using integer array indexing and the "axis" option in numpy's sum. For example, starting with:
import numpy as np
a = np.arange(16).reshape(4,4)
list0 = [0,1,2]
list1 = [3]
The initial array is
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
The lists of indices can be used to "select" only the rows you want from an array. For example,
a[list0,:]
is
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Also, rows of an array can be added together using the "axis=0" argument in numpy's sum, and the result is a 1D array. For example,
np.sum(a[list0,:],axis=0)
results in
array([12, 15, 18, 21])
Summing like this we can build the row-summed array row by row:
b = np.zeros((2,a.shape[1]))
b[0,:] = np.sum(a[list0,:],axis=0)
b[1,:] = np.sum(a[list1,:],axis=0)
The resulting array is
array([[12., 15., 18., 21.],
[12., 13., 14., 15.]])
A similar thing can be done for the columns, but with "axis=1" to add the columns:
c = np.zeros((2,2))
c[:,0] = np.sum(b[:,list0],axis=1)
c[:,1] = np.sum(b[:,list1],axis=1)
which yields the 2x2 array:
array([[45., 21.],
[39., 15.]])
If you want to do it in a more compact way, you could loop over the lists and combine them into a single array using vstack:
idx_lists = [list0, list1]
b = np.vstack([np.sum(a[idx_lists[n],:],0) for n in range(2)])
Stacking together the columns is a little trickier, since sum returns a 1D array, which is treated as a row. One solution is to vertically stack the rows together and take a transpose at the end:
c = np.vstack([np.sum(b[:,idx_lists[n]],1) for n in range(2)]).T