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 !
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)
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.
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)]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With