Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy ndarrays: row-wise and column-wise operations

If I wanted to apply a function row-wise (or column-wise) to an ndarray, do I look to ufuncs (doesn't seem like it) or some type of array broadcasting (not what I'm looking for either?) ?

Edit

I am looking for something like R's apply function. For instance,

apply(X,1,function(x) x*2)

would multiply 2 to each row of X through an anonymously defined function, but could also be a named function. (This is of course a silly, contrived example in which apply is not actually needed). There is no generic way to apply a function across an NumPy array's "axis", ?

like image 483
hatmatrix Avatar asked Oct 13 '11 16:10

hatmatrix


1 Answers

First off, many numpy functions take an axis argument. It's probably possible (and better) to do what you want with that sort of approach.

However, a generic "apply this function row-wise" approach would look something like this:

import numpy as np

def rowwise(func):
    def new_func(array2d, **kwargs):
        # Run the function once to determine the size of the output
        val = func(array2d[0], **kwargs)
        output_array = np.zeros((array2d.shape[0], val.size), dtype=val.dtype)
        output_array[0] = val
        for i,row in enumerate(array2d[1:], start=1):
            output_array[i] = func(row, **kwargs)
        return output_array
    return new_func

@rowwise
def test(data):
    return np.cumsum(data)

x = np.arange(20).reshape((4,5))
print test(x)

Keep in mind that we can do exactly the same thing with just:

np.cumsum(x, axis=1)

There's often a better way that the generic approach, especially with numpy.

Edit:

I completely forgot about it, but the above is essentially equivalent to numpy.apply_along_axis.

So, we could re-write that as:

import numpy as np

def test(row):
    return np.cumsum(row)

x = np.arange(20).reshape((4,5))
print np.apply_along_axis(test, 1, x)
like image 71
Joe Kington Avatar answered Oct 07 '22 23:10

Joe Kington