2016-11-09 64 views
5

Bir işlev kümesini bir değere uygulamak ve çıktı olarak bir değerler kümesi almak istiyorum. Yapabileceğimiz help?> groupby (DataFrames paketinde) 'de bakın:julia lang - bir değere birden fazla işlev nasıl uygulanır

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

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

ama yapabileceğimiz

> [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 

hatta

> [sum, length](1:5) 

Ben çıkışı beklenir:

[15, 5] 

cevap

7

Evet ve hayır. (yani evet o ama hayır, o sözdizimi ile mümkündür):


No: Eğer |> ve dataframes gördüğümüz sözdizimi genel sözdizimi değildir. Veri çerçeveleri için |> yönteminin nasıl tanımlandığıdır. grouping.jl dosyasındaki tanımına bakın (satır 377) ve bunun yalnızca başka bir işlevin sarıcı olduğunu ve bir işlevi veya işlevlerin bir vektörünü kabul etmek üzere tanımlandığını göreceksiniz.

Not: Not "boru" bir işlev içine bir argüman, sadece sağ tarafta 1-argüman fonksiyonlarını beklediğini ve bu özel "dataframe-aşırı" yöntemi ile yapmak için çok az vardır jenerik |>.


Evet: başka yollardan da girdi kümesine fonksiyonların kümesi uygulayabilirler.
Basit bir yol, örn. Bir liste anlayışı ile olacaktır:

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) 

Veya kullanarak map:

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

vb


Not: bunu başarmak için |> kullanmaya istekli konum ise açıkça böyle bir şey de yapabilirsiniz:

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

ama muhtemelen Eğer yapmak :)

+1

Teşekkür kaynak kodunu işaret için. Bunu başarmak için genişletebilirim: '' '' '' '' import base.(|>) (|>) {T <: İşlev} (a :: Array, fs :: Vector {T}) = [f (a) f içinde f için] > 1: 5 |> toplamak |> [toplam uzunluk] 2 öğe Dizisi {Int64,1}: '' ' – Phuoc

1

Sizin önerilen sözdizimi tip Array{T} (burada bir yöntemi ekleyerek Julia mümkündür, T alt tipleri ile sınırlıdır çalıştığın şey amacı yendi) Function ait:

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 

Ancak bu büyük bir yüke sahiptir fonksiyonların sayısı küçükse. Maksimum hızda, bir Tuple s kullanabilir ve bir @generated fonksiyon manuel döngü göz önüne sermek için:

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

Bu mükemmel bir yanıttır. Julia'nın meta programlaması hakkında daha fazla şey öğreneceğim, http://docs.julialang.org/en/release-0.5/manual/metaprogramming/ – Phuoc