I know Python starts initial index of a array from 0 and I also know x[:,:k] means first k column of array x, then I try
## prepare array
x = np.array([1, -2, 0, -2, 5, 0, 0, 0, 2]).reshape(3,-1)
x
## use cumsum
x1 = np.cumsum(x,axis=1)
x1
## manually compute
x2 = np.zeros(x.shape)
for k in range(x.shape[1]):
x2[:,k] = np.sum(x[:,:k],axis=1)
x2
However, I found x1 is inconsistent with x2. Why?
CodePudding user response:
In [20]: x = np.array([1, -2, 0, -2, 5, 0, 0, 0, 2]).reshape(3,-1)
In [21]: x
Out[21]:
array([[ 1, -2, 0],
[-2, 5, 0],
[ 0, 0, 2]])
x is symmetric, but the cumsum is not.
In [22]: np.cumsum(x,axis=1)
Out[22]:
array([[ 1, -1, -1],
[-2, 3, 3],
[ 0, 0, 2]], dtype=int32)
The first column is the same as in x. The 2nd is x[:,0] x[:,1], etc.
Change the axis, and the result is just the transpose.
In [23]: np.cumsum(x,axis=0)
Out[23]:
array([[ 1, -2, 0], # x[0,:]
[-1, 3, 0], # x[0,:] x[1,:]
[-1, 3, 2]], dtype=int32)
We can iterate across the columns with:
In [25]: res = np.zeros((3,3),int)
...: res[:,0] = x[:,0]
...: for i in range(1,3):
...: res[:,i] = res[:,i-1] x[:,i]
...:
In [26]: res
Out[26]:
array([[ 1, -1, -1],
[-2, 3, 3],
[ 0, 0, 2]])
Your iteration is has 0 in the first column, not x[:,0]:
In [27]: res = np.zeros((3,3),int)
...: for i in range(0,3):
...: res[:,i] = x[:,:i].sum(axis=1)
...:
In [28]: res
Out[28]:
array([[ 0, 1, -1],
[ 0, -2, 3],
[ 0, 0, 0]])
That's because the :i does not include i.
In [29]: res = np.zeros((3,3),int)
...: for i in range(0,3):
...: res[:,i] = x[:,:i 1].sum(axis=1)
...:
In [30]: res
Out[30]:
array([[ 1, -1, -1],
[-2, 3, 3],
[ 0, 0, 2]])
CodePudding user response:
Using numpy in loops in not a recommended way, particularly when numpy have equivalent modules. But, in case of this question, you can do this as:
x2 = np.zeros(x.shape)
for k in range(x.shape[1]):
for j in range(x.shape[0]):
x2[k, j] = np.sum(x[k, :j 1])
or if axis=0:
x2 = np.zeros(x.shape)
for k in range(x.shape[1]):
for j in range(x.shape[0]):
x2[j, k] = np.sum(x[:j 1, k])
If you want to know how to modify your code, you must use k 1 instead of k in np.sum because range is starting from 0 --> :k will be :0 ==> :k 1 will be :1
x2 = np.zeros(x.shape)
for k in range(x.shape[1]):
x2[:, k] = np.sum(x[:, :k 1], axis=1)
