简体   繁体   English

MATLAB中“过滤器”的等效Python函数是什么?

[英]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会为您提供TrueFalse数组,其大小与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/


Bonus 奖金

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM