Reputation: 3066
I want to do apply a filter
function on a vector in MATLAB.
In Python I write:
l = [1,2,3,4]
l2 = filter(lambda x:x>2,l)
How do I write this in MATLAB?
Upvotes: 1
Views: 1724
Reputation: 165
To expand on the example (bonus) answer of @rayryeng :
function out = filter_python(in, func) out = in(func(in)); end
This idea could be expanded to whole rows of data in a 2D array.
function out = filtrow(func,in,colnum)
if nargin == 2
colnum=0;
sz = size(in);
if sz(1)==1 || sz(2)==1
out = in(func(in));
return
else
out = in;
for i = sz(2):-1:1
out = out(func(out(:,i)),:);
end
end
end
if nargin == 3
out = in(func(in(:,colnum)),:);
end
Or if you'd prefer by cols.
function out = filtcol(func,in,rownum)
if nargin == 2
rownum=0;
sz = size(in);
if sz(1)==1 || sz(2)==1
out = in(func(in));
return
else
out = in';
for i = sz(2):-1:1
out = out(func(out(:,i)),:);
end
out = out';
end
end
if nargin == 3
out = in';
out = out(func(out(:,rownum)),:);
out = out';
end
So given matrix A:
A =
0 0.4694 0.1656 0.0838 0.0782 0.8687 0.1818
0.0540 0 0.6020 0.2290 0.4427 0.0844 0.2638
0.5308 0.3371 0 0.9133 0.1067 0.3998 0.1455
0.7792 0.1622 0.6541 0 0.9619 0.2599 0.1361
0.9340 0.7943 0.6892 0.8258 0.0046 0.8001 0.8693
0.1299 0.3112 0.7482 0.5383 0.7749 0.4314 0.5797
0.5688 0.5285 0.4505 0.9961 0.8173 0.9106 0.5499
#%%% We can also remove entire rows or cols by this method
#%%% here we use filtrow to remove rows where elements do no pass the c condition function
>> out = filtrow(@(x) x>0,A)
out =
0.9340 0.7943 0.6892 0.8258 0.0046 0.8001 0.8693
0.1299 0.3112 0.7482 0.5383 0.7749 0.4314 0.5797
0.5688 0.5285 0.4505 0.9961 0.8173 0.9106 0.5499
#%%% Or we can do the same to remove the cols
>> out = filtcol(@(x) x>0,A)
out =
0.0782 0.8687 0.1818
0.4427 0.0844 0.2638
0.1067 0.3998 0.1455
0.9619 0.2599 0.1361
0.0046 0.8001 0.8693
0.7749 0.4314 0.5797
0.8173 0.9106 0.5499
#%%%Or you could filter by individual rows
>> out = filtrow(@(x) x>0,A,1)
out =
0.0540 0 0.6020 0.2290 0.4427 0.0844 0.2638
0.5308 0.3371 0 0.9133 0.1067 0.3998 0.1455
0.7792 0.1622 0.6541 0 0.9619 0.2599 0.1361
0.9340 0.7943 0.6892 0.8258 0.0046 0.8001 0.8693
0.1299 0.3112 0.7482 0.5383 0.7749 0.4314 0.5797
0.5688 0.5285 0.4505 0.9961 0.8173 0.9106 0.5499
Upvotes: 0
Reputation: 104504
The closest equivalent in MATLAB is to use logical
indexing to filter out elements you don't need:
l = [1,2,3,4];
l2 = l(l > 2);
What filter
in Python does is that it returns another list given that the predicate you specify for each element in your list evaluates to True
. Any elements that are False
are removed from the list. On that same token, in MATLAB, you can directly index into an array with logical
indexing to give you the same thing.
So what exactly does l2 = l(l > 2);
do? Basically, l > 2
gives you an array of True
and False
that is the same size as l
. It will look like this in MATLAB:
>> l = [1,2,3,4]
l =
1 2 3 4
>> l > 2
ans =
0 0 1 1
As you can see, l > 2
returns a logical
vector that is the same size as l
. What is shown here is whether or not each value of l
satisfied the predicate of it being greater than 2. As expected, the first two elements are False
while the last two elements are True
. By using this logical
vector as input into your vector l
, you are indexing so that any locations that are equal to True
in this vector, the corresponding locations in l
are selected whereas the locations that are False
get filtered out. As such, the first two elements are removed because they are False
while the last two elements stay because those locations are True
.
Therefore, doing l2 = l(l > 2);
thus gives:
>> l2 = l(l > 2)
l2 =
3 4
Read more about logical
indexing here from Steve Eddins's blog: http://blogs.mathworks.com/steve/2008/01/28/logical-indexing/
However, if you really want to use the filter
paradigm, you can define a function that can do it like so:
function out = filter_python(in, func)
out = in(func(in));
end
This does no error checking and you need to make sure that func
is a function that accepts a vector and that the output is also a vector as the same size as the input vector in
. The function also needs to return True/False
for each element in the input vector.
Note that I'm calling this filter_python
because filter
is a function that already exists in MATLAB that's part of the Signal Processing Toolbox. Save this to a file called filter_python.m
. Now that you're done, you'd call it like this:
l = [1,2,3,4];
l2 = filter_python(l, @(x) x > 2);
@(x)
is an anonymous function, much like lambda x
is in Python.
As a bonus, in IPython, this is what we get:
In [13]: %paste
l = [1,2,3,4]
l2 = filter(lambda x:x>2,l)
## -- End pasted text --
In [14]: l
Out[14]: [1, 2, 3, 4]
In [15]: l2
Out[15]: [3, 4]
.... and in MATLAB (as we showed earlier):
>> l = [1,2,3,4];
>> l2 = l(l > 2);
>> l2
l2 =
3 4
Similarly with the custom function:
>> l = [1,2,3,4];
>> l2 = filter_python(l, @(x) x > 2);
>> l2
l2 =
3 4
Upvotes: 2