Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operation on 2d array columns

Tags:

python

arrays

2d

I'd like to know if it's possible to apply a function (or juste an operation, such as replacing values) to column in a python 2d array, without using for loops.

I'm sorry if the question has already been asked, but I couldn't find anything specific about my problem.

I'd like to do something like :

array[:][2] = 1

Which would mean put 1 for each value at the third column, or

func(array[:][2])

Which would mean apply func() to the third column of array.

Is there any magic python-way to do it ?

EDIT : The truth has been spoken. I forgot to say that I didn't want to avoid for() statement to improve performance, but just because I don't wan to add multiples lines for this precise instance. We got 2 answers here, one in a native way, and two more with the help of Numpy. Thanks a lot for your answers !

like image 345
Coulis Avatar asked Sep 22 '15 14:09

Coulis


Video Answer


3 Answers

Without numpy it can be done like this:

map(lambda x: x[:2] + [1] + x[3:], array)

map(lambda x: x[:2] + my_func(x[2]) + x[3:], array)
like image 143
Eugene Soldatov Avatar answered Oct 26 '22 21:10

Eugene Soldatov


You can do this easily with numpy arrays. Example -

In [2]: import numpy as np

In [3]: na = np.array([[1,2,3],[3,4,5]])

In [4]: na
Out[4]:
array([[1, 2, 3],
       [3, 4, 5]])

In [5]: na[:,2] = 10

In [6]: na
Out[6]:
array([[ 1,  2, 10],
       [ 3,  4, 10]])

In [7]: na[:,2]
Out[7]: array([10, 10])

In [8]: def func(a):
   ...:     for i,x in enumerate(a):
   ...:         a[i] = x + 1
   ...:

In [9]: na
Out[9]:
array([[ 1,  2, 10],
       [ 3,  4, 10]])

In [10]: func(na[:,1])

In [11]: na
Out[11]:
array([[ 1,  3, 10],
       [ 3,  5, 10]])

You can find more details about this here . Please do be careful , for numpy arrays, as stated in documentation -

All arrays generated by basic slicing are always views of the original array.

This is why when changing the sliced array inside the function, the actual array got changed.

like image 43
Anand S Kumar Avatar answered Oct 26 '22 22:10

Anand S Kumar


It would be very simple in numpy and you can do it with a simple assignment :

>>> numpy.array[:,column_number]=value

But if you are looking for a python approach you can use zip function and itertools.repeat():

>>> from itertools import repeat
>>> def replacer(l,index,value):
...     z=zip(*l)
...     z[index]=list(repeat(value,len(l)))
...     return zip(*z)

Demo:

>>> l=[range(4) for _ in range(3)]
>>> replacer(l,2,'*')
[(0, 1, '*', 3), (0, 1, '*', 3), (0, 1, '*', 3)]

Note that since in python 3.X zip returns an iterator you can use list function to return a list also since iterators doesn't support indexing inside the function you need to call the list too.

>>> def replacer(l,index,value):
...     z=list(zip(*l))
...     z[index]=list(repeat(value,len(l)))
...     return zip(*z)

>>> list(replacer(l,2,'*'))
[(0, 1, '*', 3), (0, 1, '*', 3), (0, 1, '*', 3)]
like image 33
Mazdak Avatar answered Oct 26 '22 21:10

Mazdak