Reputation: 194
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 !
Upvotes: 9
Views: 2254
Reputation: 5658
you can map a function to each column....
ar = [[1,2,3],
[3,4,5],
[3,4,5],
[3,4,5],
[3,4,5]]
if you want change second column to 100:
def column_change(l,n =1 , m =100):
l[n] = m
return l
print(list(map(colum_change,ar)))
[[1, 100, 3], [3, 100, 5], [3, 100, 5], [3, 100, 5], [3, 100, 5]]
Upvotes: 2
Reputation: 107287
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)]
Upvotes: 2
Reputation: 90899
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.
Upvotes: 7
Reputation: 10135
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)
Upvotes: 7