xolodec
xolodec

Reputation: 843

Python column addition of numpy arrays with shift

How can i accomplish column addition with shift using python numpy arrays ?

I have two dimensional array and need it's extended copy.

a = array([[0, 2, 4, 6, 8],
       [1, 3, 5, 7, 9]])

i want something like (following is in pseudo code, it doesn't work; there is no a.columns in numpy as far as i know):

shift = 3
mult_factor = 0.7
for column in a.columns - shift :
    out[column] = a[column] + 0.7 * a[column + shift] 

I also know, that i can do the something similar to what i need using indexes. But i seems that is really overkill enumerating three values and using only one (j) :

for (i,j),value in np.ndenumerate(a):
    print i,j

I founded, that i could iterate over columns, but not their indexes:

for column in a.T:
    print column

Than i though that i can simply do this with something that is similar to xrange, but applying to multidimensional array:

In [225]: for column in np.ndindex(a.shape[1]):
            print column
   .....:     
(0,)
(1,)
(2,)
(3,)
(4,)

So now i only know how to do this with simple xrange and i am not sure, that is the best solution.

out = np.zeros(a.shape)
shift = 2
mult_factor = 0.7
for i in xrange(a.shape[1]-shift):
    print a[:, i]
    out[:, i] =  a[:, i] + mult_factor * a[:, i+shift]

However it will be not so fast in Python as it maybe can be. Can you give me an advice how it will be in performance and maybe there is more faster way to accomplish column addition of numpy arrays with shift ?

Upvotes: 2

Views: 1848

Answers (2)

Greg von Winckel
Greg von Winckel

Reputation: 2261

I'm not positive I completely understand what the computed quantity should be, but here are two things that seem germane to what you are asking:

  1. If you have a 2D array, called a that you wish to convert to a list of 1D arrays which are the columns of a you can do this

    cols = [c for c in a.T]

  2. It looks like what you want can be accomplished with matrix multiplication if I am not mistaken. You could make a banded matrix in numpy using numpy.diag or, since you would have the same values along each band 1, mult_factor, or 0, you could use scipy.linalg.toeplitz

    m,n = a.shape
    band = np.eye(1,n)
    band[0,shift] = mult_factor
    T = scipy.linalg.toeplitz(np.eye(1,m),band)
    out = np.inner(a,T)

For large matrices, it might make sense to use a sparse matrix for T if you only want to add two or a few columns of a.

Upvotes: 0

user2357112
user2357112

Reputation: 281624

out = a[:, :-shift] + mult_factor * a[:, shift:]

I think this is what you're looking for. It's a vectorized form of your loop, operating on large slices of a instead of column by column.

Upvotes: 2

Related Questions