pythonrsv分割_量化投资与python学习笔记(二)

这一篇的主题,我们来谈一谈如何不用for遍历,以及一定要用循环遍历的话,如何优雅。

我不是要逼你用while循环,我是在讨论优雅的遍历方法,这里优雅的标准是,代码简洁清晰,时间复杂度方面也高效,同时兼具python“implicit is better than explicit”的准则。

用for 循环有一个不好的地方在于代码不易读,但是写成列表解析的方式会非常清晰:

def process(item):

...

...

return result

result= [process(item) for item in list]

#列表解析的优雅 类似于 优雅的定义函数:

In [3]: (lambda x:x>2)(np.arange(10))

Out[3]: array([False, False, False, True, True, True, True, True, True, True], dtype=bool)

In [4]: [i+j for i in range(5) for j in range(i)]

Out[4]: [1, 2, 3, 3, 4, 5, 4, 5, 6, 7]

In [5]: [j for i in range(5) for j in range(i)]

Out[5]: [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

当然也有很多时候不用写for循环,还可以用一些比较pythonic的函数。比如:

1. map

如果你想把一个list映射到另一个list,可以用map函数

oldlist=range(5)

square=map(lambda x:x**2,oldlist)

print square

[0, 1, 4, 9, 16]

“扁平结构比嵌套结构更好” – 《Python之禅》

比如 list(map(lambda x:4 if x==3 else x),a)

如果一定要用for:

a = [1, 2, 3, 4, 5, 6]

3变成4

[4 if x==3 else x for x in a]

b = [1, 2, 4, 4, 5, 6]

删除4

[x for x in b if x != 4]

也是可以的。。

2.filter

In [88]: filter(lambda x:x%2==1,[1,4,6,7,9,12,17])

Out[88]: [1, 7, 9, 17]

3.apply与rolling

rolling返回的是一个ndarray,如果要用对Series的方法,如rank(),才能使用。例如,想要知道当前的因子值是过去40根bar中的排名,俗称ts_rank(x,40),实现方法:

In [26]:a=pd.Series(np.random.random(10))

0 0.537490

1 0.008421

2 0.075805

3 0.205377

4 0.063493

5 0.893637

6 0.554811

7 0.727446

8 0.355941

9 0.543967

dtype: float64

In [27]:a.rolling(3).apply(lambda x:pd.Series(x).rank()[3-1])

Out[27]:

0 NaN

1 NaN

2 2.0

3 3.0

4 1.0

5 3.0

6 2.0

7 2.0

8 1.0

9 2.0

dtype: float64

然而上面这个操作的不是很优雅,原因在于python自带的pd.rank()函数返回的是所有元素的排名对应的Series,但是我们只关心当前的因子在前M根bar中的排名,我们可以使用如下更为优雅的方法,速度大概快了30倍左右。

a.rolling(M).apply(lambda x:(x>x[-1]).sum()+1)

不过这个方法的缺点在于没有考虑元素相同的情况下的平均排名。意思是例如[1,2,3,4,4,4],4的排名就是6,5,4,rank()会返回5。我们的简约算法会返回排名中的最小值4。值得庆幸的是,ts_rank一般考虑的周期比较大,例如120,那么119.5相对于120的差别较4与5的差别可以忽略不计了。

4.根据需要的时间点取出对应行,并做相同操作。

df.loc[df.time.isin(timelist)]#可以取出想要的行

这个操作就是很典型的解释性语言的风格,凸显了implicit的风格,而喜欢explicit风格的人自然想到了用for循环。

比如下面:

[i in timelist for i in df.time]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值