2016-11-09 5 views
5

に複数の機能を適用する方法を、私は値に関数のセットを適用し、出力として一連の値を取得したいと思います。私たちが行うことができます(データフレームパッケージ)help?> groupbyで参照してください。ジュリアLANG - 値

> df |> groupby(:a) |> [sum, length] 

> df |> groupby([:a, :b]) |> [sum, length] 

が、我々は

> [sum, length](groupby([:a, :b])) 
MethodError: objects of type Array{Function,1} are not callable 
square brackets [] for indexing an Array. 
eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64 
    in macro expansion at ./REPL.jl:95 [inlined] 
    in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68 

あるいは

> [sum, length](1:5) 

を行うことができ、私は出力を期待する:

[15, 5] 

答えて

7

はい、いいえ。(はい、可能ですが、その構文ではありません):


いいえ: |>とdataframesで表示される構文は一般的な構文ではありません。それはちょうど |>メソッドがデータフレームのために定義されている方法です。ファイル grouping.jl(ライン377)でその定義を参照してください、あなたはそれが別の関数への単なるラッパーだし、関数、または関数のベクトルを受け入れるようにどちらかの定義されています表示されます。

PS:関数に引数をパイプする「|>」は、この特定の「dataframe-overloaded」メソッドとはあまり関係がないことに注意してください。


はい: あなたは他の方法での入力の集合への関数のセットを適用することができます。
一つの簡単な方法は、例えばリスト内包を経由して次のようになります。

julia> a = [1 2 3;2 3 4]; 
julia> [f(a) for f in [sum, length, size]] 
3-element Array{Any,1}: 
15  
    6  
    (2,3) 

またはmapを使用して:

julia> map((x) -> x(a), [sum, length, size]) 

など


PS:あなたがこれを達成するために|>を使用することに熱心であれば、

:はっきりあなたも、このような何かを行うことができます
julia> a |> (x) -> [sum(x), length(x), size(x)] 

が、おそらくそれはあなたが何をしようとしての目的に反し:)

+1

ありがとう:最大速度のために、一つは手動でループをアンロールするTuple Sおよび@generated関数を使用することができます。私は達成するためにそれを拡張することができます: '' '輸入基地。> 1:5 |> collect |> (|>){T :: Function}(a ::配列、fs :: Vector {T})= [fのfのf [合計、長さ] 2要素配列{Int64,1}: '' ' – Phuoc

1

あなたの提案構文はここにタイプArray{T}(にメソッドを追加することにより、ジュリアに可能であるが、Tは、サブタイプに制限されています)Functionの:機能の数が少ない場合

julia> (a::Array{T}){T<:Function}(x) = [f(x) for f in a] 

julia> [sin cos; exp sqrt](0) 
2×2 Array{Float64,2}: 
0.0 1.0 
1.0 0.0 

しかし、これは大きなオーバヘッドを有します。ソースコードを指摘するため

julia> @generated (t::NTuple{N, Function}){N}(x) = :($((:(t[$i](x)) for i in 1:N)...),) 

julia> (cos, sin)(0) 
(1.0,0.0) 
+0

これは優れた答えです。私はジュリアのメタプログラミングについてもっと学びます。http://docs.julialang.org/en/release-0.5/manual/metaprogramming/ – Phuoc