【问题标题】:How to select elements from array in Julia matching predicate?如何从 Julia 匹配谓词中的数组中选择元素?
【发布时间】:2015-03-09 04:29:59
【问题描述】:

Julia 似乎有很多类似于 Matlab 的功能。我想使用谓词从数组中进行选择。在 Matlab 中我可以这样做:

>> a = 2:7 ;
>> a > 4

ans =

     0     0     0     1     1     1

>> a(a>4)

ans =

     5     6     7

我在 Julia 中发现了一种看似笨拙的方式来完成其中的一部分:

julia> a = 2:7
2:7

julia> [int(x > 3) for x in a]
6-element Array{Any,1}:
 0
 0
 1
 1
 1
 1

(使用维基百科所说的list comprehension)。我还没有想出如何在 Julia 中应用这样的集合来选择,但可能会叫错树。如何在 Julia 中从数组中进行谓词选择?

【问题讨论】:

    标签: arrays julia


    【解决方案1】:

    我想添加一个之前的答案未涵盖的方面。如果您想通过索引值(而不是数组值)过滤数组,您可以通过a[1:end ...] 执行此操作,而不是点,您将广播运算符应用于索引值。例如。为了删除你要写的第三个元素

    a[1:end .!= 3].
    

    【讨论】:

    • 这个实例也允许 a[1:end .!= [2,3]] 但是要小心,因为 a[1:end .!= []] 会抛出异常
    【解决方案2】:

    我目前使用的是 Julia 1.3.1,与之前的答案相比,一些语法发生了变化。要在多个条件下过滤数组,我必须这样做:

    x = range(0,1,length=100)
    x[(x .> 0.4) .& (x .< 0.51)] 
    

    注意执行 AND 运算符所需的“.&”。

    【讨论】:

      【解决方案3】:

      要过滤字典中的键,这对我有用:

      mydict = Dict("key1" => 1.0, "key2" => 2.0, "a big string with a part of a string" => 3.0)
      filter(x -> occursin("part of a string", string(x)), keys(mydict))
      

      这是 Julia 1.0 中 REPL 上的输出结果

      julia> mydict = Dict("key1" => 1.0, "key2" => 2.0, "a big string with a part of a string" => 3.0)
      Dict{String,Float64} with 3 entries:
        "key2"                                 => 2.0
        "key1"                                 => 1.0
        "a big string with a part of a string" => 3.0
      
      julia> filter(x -> occursin("part of a string", string(x)), keys(mydict))
      Set(["a big string with a part of a string"])
      

      这通常是过滤字符串数组的好方法。

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        Julia 中的数组解析比 Haskell 或 Python 中的列表解析更原始。有两种解决方案——你可以使用高阶过滤函数,或者使用广播操作。

        高阶过滤

        filter(x -> x > 4, a)
        

        这会使用谓词 x -&gt; x &gt; 4 调用 filter 函数(请参阅 Julia 手册中的匿名函数)。

        广播和索引

        a[Bool[a[i] > 4 for i = 1:length(a)]]
        

        这会在a 和4 的元素之间执行广播比较,然后使用生成的布尔数组来索引a。使用广播运算符可以更紧凑地编写它:

        a[a .> 4]
        

        【讨论】:

        • 我有一个数组,并且想过滤它不止一件事。例如 a > 3 && a
        • 这适用于filterfilter( x -&gt; (x &gt; 3 &amp;&amp; x &lt; 5), a) docs.julialang.org/en/latest/stdlib/collections/…
        • 对于数组,您必须使用按位运算符a .&gt; 3 &amp; a .&lt; 5 注意&amp; 的单个bitwise and
        • 请注意,a=[1; 2; 3]; a[a.&gt;0 &amp; a.&lt;1] 不会产生预期的结果!这给出了1 2 3,因为&amp; 运算符具有更高的优先级。正确的解决方案是a[(a.&gt;0) &amp; (a.&lt;1)]
        【解决方案5】:

        如果您使用点 . 进行 elementwise 比较,则可以使用非常类似于 Matlab 的语法:

        julia> a = 2:7
        2:7
        
        julia> a .> 4
        6-element BitArray{1}:
         false
         false
         false
          true
          true
          true
        
        julia> a[a .> 4]
        3-element Array{Int32,1}:
         5
         6
         7
        

        或者,如果您想要更实用的谓词方法,您可以调用filter

        julia> filter(x -> x > 4, a)
        3-element Array{Int32,1}:
         5
         6
         7
        

        【讨论】:

        • 据记录,元素方法的速度大约是调用过滤器的两倍。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 2017-07-24
        • 1970-01-01
        • 1970-01-01
        • 2014-06-22
        相关资源
        最近更新 更多