2016-11-09 70 views
5

我想將一組函數應用於某個值並獲取一組值作爲輸出。我看到help?> groupby(DataFrames包),我們可以這樣做:julia 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:請注意,一般的|>其中「管道」的參數轉換爲一個函數,只希望在右手側1參數函數,並且具有很少做此特定「數據幀重載」的方法。


是: 您可以將一組函數的一組在其他方面的投入。
一個簡單的方法,例如將通過列表理解:

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

感謝您指出的源代碼。我可以擴展它以實現:'''import base。(|>) (|>){T <:Function}(a :: Array,fs :: Vector {T})= [f(a)for f in fs] > 1:5 |> collect |> [sum,length] 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 

但是,這有一個大的開銷,如果功能的數量較少。爲了獲得最大的速度,可以使用Tuple S和@generated功能手動展開循環:

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

這是一個很好的答案。我將詳細瞭解Julia的元編程,http://docs.julialang.org/en/release-0.5/manual/metaprogramming/ – Phuoc

相關問題