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)