一、map的方便之处
比如,进行矩阵(更准确是向量)计算,如果函数内参数没有写矩阵格式(::Array{}),只写了(比如:::Float64),这时用map可以很方便得到矩阵返回值,不需要写循还。
比如,我写了一个getDateTime(dt::ASCIIString)函数(返回值为Dates.DateTime),如果要对["2014-1-15", "2014-1-16"]进行运算,julia> map(getDateTime,["2014-1-15", "2014-1-16"]);
注:不过,暂时只发现了可以进行向量式计算,矩阵在这里也会转成向量的。
二、匿名函数
和C#等一样,如果你在Julia中,如果是一个简单的函数,你又不想写一个函数,便可以用匿名函数了。
julia> map(x->x^2+sin(x), [1,2,3,4,5]); # 单参数
julia>map((x,y)->sin(x+y^2), [1,2] , [5,10]) # 多参数
julia>map((x,y)->(x+y^2+3*y),[1,2] , [5,10]) # 更复杂一点的格式
如果某函数稍复杂一些,可以先把函数简化一下:
简化方法:
fun(x,y)=x+y^3+3*y+5*x^2+sin(x-2*y)+cos(y-x/2) # 写一个简化的函数,省得写function fun(x,y)......end 格式
再
julia>map((x,y)->fun(x,y),[1,2],[5,10]) # 这样更优雅一些。
但,没办法写成:
julia>map(fun,[1,2],[5,10]) # 不能这么写,Julia会报错!
还比如,我有一个自定义的类型,kbarData,里面有 Open,Close,High,Low....等字段,如何取得Close的序列
julia> map(bar->bar.Close,data); #data:Array{kbarData,1}
注意不能,map(bar.Close,data)
从上面可以看到,Julia的确做到了优雅!赞!
三、三种“差之毫厘,谬之千里”的格式
事实上,map(x->x^2+sin(x), [1,2,3,4,5]);也有其它的写法,功能差不多。
(1)julia>data =[x^2+sin(x) for x in [1,2,3,4,5]] # typeof(data) 为Array{Float64,1}. 这个和map()效果完全一样。
其中, julia>data =[sin(x+y^2) for x in [1,2] , y in [5,10]] # 多参数格式
(2)julia>data ={x^2+sin(x) for x in [1,2,3,4,5]} #不过返回的类型为:Array{Any,1},只能说实际效果相当,略有区别了。
比如,以下是我在一个函数中用到的代码:
# 日期 时间 今开 最高 最低 收盘 成交量 成交金额
CodeInTable =repmat([code],row,1)
dt =map((x,y)->getDateTime(string(x," ",y)), data[:,1],data[:,2]) # 原格式: 2014/1/5 9:31:00
TradeDay = [Dates.year(x)*10000+Dates.month(x)*100+Dates.day(x) for x in dt]
TradeTime =[Dates.hour(x)*10000+Dates.minute(x)*100+Dates.second(x) for x in dt]
如果是写循还,那代码的体格可能要上升N倍。但需要注意,这种写法可能会导致性能会下降。
同样,对于kbarData类型,
map(x->x.Close,data) 可以写成 :[bar.Close for bar in data]
但要注意,如下写成下面的格式,可能情况就另当别论了。
(1)注意:写成以下格式,返回值为一个函数Array了
julia>data =[x^2+sin(x) for x in [1,2,3,4,5]]
(2)还需注意,写成以下格式,返回值变成一个Dict()
julia>data =[x=>x^2+sin(x) for x in [1,2,3,4,5]]
四、关于速度
在Julia中,匿名函数(带"->",不带的不算匿名函数,特此说明。)因为速度相对较慢,是不推荐的。其实,我们也可以从下面的比较可以得到。
以sin(x)为例:
map(sin,data) 远优于map(x->sin(x),data); # 我机器上测效率差13倍
而:
map(x->sin(x),data) 要优于[sin(x) for x in data]. #我机器上测,效率差1倍
但一个基本简单的原则是,所有的这些“优雅”都是有代价的,如果要追单最好的速度,还是请用循还吧。这也许就是大道至简吧。
这里面,最值得推荐的还是map()非匿名的写法,又优雅,速度又快!
这所谓,“差之毫厘,谬之千里”!信不信由你。