traumatologo - ¿Cuál es el estilo idiomático de Julia para operaciones de columna o fila?
sintomas de rechazo de protesis de columna (3)
Creo que @ivarne tiene la respuesta correcta (y la he marcado), pero simplemente agregué que hice una función de apply
como:
function aaply(fun::Function, dim::Integer, ar::Array)
if !(1 <= dim <= 2)
error("rows is 1, columns is 2")
end
if(dim==1)
res= [fun(ar[row, :]) for row=1:size(ar)[dim]]
end
if(dim==2)
res= [fun(ar[:,col]) for col=1:size(ar)[dim]]
end
return res
end
esto entonces obtiene lo que quiero como tal:
julia> aaply(quantile, 2, test)
2-element Array{Any,1}:
[0.231621,0.265787,0.266542,0.267048,0.267824]
[0.173984,0.174021,0.191191,0.20863,0.210059]
donde quantile
es una función incorporada que proporciona min, lq, mediana, uq y max .. al igual que microbenchmark.
EDITAR Siguiendo los consejos aquí, probé la nueva función mapslice
que funciona de manera muy parecida a R y la mapslice
con la función anterior. Tenga en cuenta que mapslice
tiene dim=1
según el segmento de la columna mientras que la test[:,1]
es la primera columna ... ¿entonces lo opuesto a R aunque tiene la misma indexación?
# nonsense test data big columns
julia> ar=ones(Int64,1000000,4)
1000000x4 Array{Int64,2}:
# built in function
julia> ms()=mapslices(quantile,ar,1)
ms (generic function with 1 method)
# my apply function
julia> aa()=aaply(quantile, 2, ar)
aa (generic function with 1 method)
# compare both functions
julia> aaply(quantile, 2, timer1([ms, aa], 40))
2-element Array{Any,1}:
[0.23566,0.236108,0.236348,0.236735,0.243008]
[0.235401,0.236058,0.236257,0.236686,0.238958]
Así que las diversiones son aproximadamente tan rápidas como la otra. Al leer los bits de la lista de correo de Julia, parece que intentan hacer un poco de trabajo en este bit de Julialang, de modo que hacer porciones es una referencia en lugar de hacer nuevas copias de cada porción (fila de columna, etc.) ...
Disculpas si esto es bastante general, aunque sigue siendo una cuestión de codificación.
Con un poco de tiempo en mis manos he estado tratando de aprender un poco de Julia
. Pensé que un buen comienzo sería copiar la función de microbenchmark
R
, para poder comparar a la perfección las funciones R y Julia.
por ejemplo, esta es microbenchmark
salida de microbenchmark
para las funciones 2 R que estoy tratando de emular:
Unit: seconds
expr min lq median uq max neval
vectorised(x, y) 0.2058464 0.2165744 0.2610062 0.2612965 0.2805144 5
devectorised(x, y) 9.7923054 9.8095265 9.8097871 9.8606076 10.0144012 5
Hasta ahora, en Julia, estoy intentando escribir código idiomático y, con suerte, comprensible / conciso. Por lo tanto, reemplacé un bucle doble con una lista de comprensión para crear una serie de tiempos, como los siguientes:
function timer(fs::Vector{Function}, reps::Integer)
# funs=length(fs)
# times = Array(Float64, reps, funs)
# for funsitr in 1:funs
# for repsitr in 1:reps
# times[reps, funs] = @elapsed fs[funs]()
# end
# end
times= [@elapsed fs[funs]() for x=1:reps, funs=1:length(fs)]
return times
end
Esto da una serie de tiempos para cada una de las 2 funciones:
julia> test=timer([vec, devec], 10)
10x2 Array{Float64,2}:
0.231621 0.173984
0.237173 0.210059
0.26722 0.174007
0.265869 0.208332
0.266447 0.174051
0.266637 0.208457
0.267824 0.174044
0.26576 0.208687
0.267089 0.174014
0.266926 0.208741
Mi pregunta (finalmente) es ¿cómo aplico idiomáticamente una función como min
, max
, median
entre columnas (o filas) de una matriz sin usar un bucle?
Por supuesto, puedo hacerlo fácilmente para este caso simple con un bucle (sim al que taché arriba), pero no puedo encontrar nada en los documentos que sea equivalente a decir apply(array,1, fun)
o incluso colMeans
.
El tipo de función genérica más cercana que puedo pensar es
julia> [mean(test[:,col]) for col=1:size(test)[2]]
2-element Array{Any,1}:
0.231621
0.237173
... pero la sintaxis realmente no apela. ¿Hay una forma más natural de apply
funciones en columnas o filas de una matriz multidimensional en Julia?
La función que desea es mapslices
.
Las funciones anónimas actualmente son lentas en julio, por lo que no las usaría para la evaluación comparativa a menos que haga una comparación de las funciones anónimas. Eso dará una predicción de rendimiento incorrecta para el código que no usa funciones anónimas en las partes críticas del código.
Creo que quiere que la versión de dos argumentos de las funciones de reducción, como sum (arr, 1), se sume sobre la primera dimensión. Si no hay una función de biblioteca disponible, puede utilizar la reducedim