[英]What is the equivalent Python function for “filter” in MATLAB?
I want to do apply a filter
function on a vector in MATLAB. 我想在MATLAB中的向量上应用filter
函数。
In Python I write: 在Python中,我这样写:
l = [1,2,3,4]
l2 = filter(lambda x:x>2,l)
How do I write this in MATLAB? 如何在MATLAB中编写此代码?
The closest equivalent in MATLAB is to use logical
indexing to filter out elements you don't need: MATLAB中最接近的等效项是使用logical
索引来过滤掉不需要的元素:
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
. Python中的filter
所做的是,给定您为列表中每个元素指定的谓词的评估结果为True
,它将返回另一个列表。 Any elements that are False
are removed from the list. 从列表中删除所有为False
元素。 On that same token, in MATLAB, you can directly index into an array with logical
indexing to give you the same thing. 同样,在MATLAB中,您可以使用logical
索引直接索引到数组中,从而为您提供相同的东西。
So what exactly does l2 = l(l > 2);
那么l2 = l(l > 2);
到底是什么l2 = l(l > 2);
do? 做? Basically, l > 2
gives you an array of True
and False
that is the same size as l
. 基本上, l > 2
会为您提供True
和False
数组,其大小与l
相同。 It will look like this in MATLAB: 在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
. 如您所见, l > 2
返回与l
大小相同的logical
向量。 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
. 这里显示的是l
每个值是否满足其大于2的谓词。正如预期的那样,前两个元素为False
,后两个元素为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. 通过将此logical
向量用作向量l
输入,您可以建立索引,以便选择此向量中等于True
任何位置,即可选择l
中的相应位置,而False
的位置将被过滤掉。 As such, the first two elements are removed because they are False
while the last two elements stay because those locations are True
. 这样,由于前两个元素为False
而删除了前两个元素,因为这些位置为True
所以保留了后两个元素。
Therefore, doing l2 = l(l > 2);
因此,做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/ 从Steve Eddins的博客中了解有关logical
索引的更多信息: 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: 但是,如果您确实要使用filter
范例,则可以定义一个可以执行此操作的函数,如下所示:
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
. 这没有错误检查,你需要确保func
是接受矢量和输出也是一个矢量一样大小的输入向量函数in
。 The function also needs to return True/False
for each element in the input vector. 该函数还需要为输入向量中的每个元素返回True/False
。
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. 请注意,我之所以称其为filter_python
,是因为filter
是MATLAB中已经存在的函数,它是Signal Processing Toolbox的一部分。 Save this to a file called filter_python.m
. 将此保存到名为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. @(x)
是一个匿名函数,就像lambda x
在Python中一样。
As a bonus, in IPython, this is what we get: 作为奖励,在IPython中,这是我们得到的:
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): ....以及在MATLAB中(如我们先前所示):
>> 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
To expand on the example ( bonus ) answer of @rayryeng : 扩展@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. 或者,如果您希望使用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:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.