Julia: map、匿名函数和“差之毫厘,谬之千里”

一、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()非匿名的写法,又优雅,速度又快!

    这所谓,“差之毫厘,谬之千里”!信不信由你。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值