版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

for…in 迭代循环首先介绍Python中最常用的for…in循环遍历的方式。for…in循环结构用于遍历列表、元组、字典、字符串、集合、文件等。其实for和in是两个独立的语法,for语句是Python内置的迭代器工具,用于从可迭代容器对象(如列表、元组、字典、字符串、集合、文件等)中逐个读取元素,直到容器中没有更多元素为止,工具和对象之间只要遵循可迭代协议即可进行迭代操作。in的存在使得python在操作可迭代对象时变得简单得多,用于配合for使用逐个取可迭代对象的元素。

for语句参与的具体迭代的过程为:可迭代对象通过iter方法返回迭代器,迭代器具有next方法,for循环不断地调用next方法,每次按序返回迭代器中的一个值,直到迭代到最后,没有更多元素时抛出异常StopIteration(Python会自动处理异常)。模拟迭代的过程如下所示:# 迭代的过程

x = [1,2,3]

its = x.__iter__() #列表是可迭代对象,否则会提示不是迭代对象

print(its)

# 打印结果:

print(next(its)) # its包含此方法,说明its是迭代器

# 打印结果:

1

print(next(its))

# 打印结果:

2

print(next(its))

# 打印结果:

3

print(next(its))

# 打印结果:

Traceback (most recent call last):

File "", line 1, in

StopIteration

迭代的优点是无需把所有元素一次加载到内存中,可以在调用next方法时逐个返回元素,避免出现内存空间不够的情况。

使用for…in循环方式实现单均线突破策略。遍历全部交易日的收盘价数值和Ma20数值,将收盘价数值减去Ma20数值,并使用np.sign()取差值符号,当收盘价在Ma20上方时差值为正,收盘价在Ma20上下方时差值为负,由负转正对应为买点,由正转负对应为卖点。如下所示def forin_looping(df):

df['signal'] = 0 #df = df.assign(signal = 0) #可采用assign新增一列

for i in np.arange(0,df.shape[0]):

df.iloc[i,df.columns.get_loc('signal')] = np.sign(df.iloc[i]['Close'] - df.iloc[i]['Ma20'])

return df

print(forin_looping(df_stockload)[0:5])

"""

High Low Open Close Volume Adj Close Ma20 signal

Date

2018-01-29 3587.0 3510.3 3563.6 3523.0 236000 3523.0 3454.3 1.0

2018-01-30 3523.1 3484.7 3511.5 3488.0 186400 3488.0 3461.3 1.0

2018-01-31 3495.5 3454.7 3470.5 3480.8 207300 3480.8 3466.8 1.0

2018-02-01 3495.1 3424.4 3478.7 3447.0 260500 3447.0 3469.9 -1.0

2018-02-02 3463.2 3388.9 3419.2 3462.1 208100 3462.1 3473.4 -1.0

"""

iterrows()生成器方式

另一种Python中常用的遍历方式为iterrows()生成器方式。所谓生成器其实是一种特殊的迭代器,内部支持了迭代器协议。Python中提供生成器函数和生成器表达式两种方式实现生成器,每次请求返回一个结果,不需要一次性构建一个结果列表,节省了内存空间。

在Python 3中可使用range返回一个迭代器,用来一次一个值地遍历一个范围.# 生成器函数方式实现生成器

def gensquares(N):

for i in range(N):

yield i**2

print(gensquares(5))

#打印结果:

for i in gensquares(5):

print(i)

# 打印结果:

0

1

4

9

16

其实yield就相当于一个return,只是return返回的是值,但是yield返回的是生成器,除了这点其他都一样,所以return也好yield也好都只能用在函数中。

生成器表达式方式实现生成器就是类似列表解析,按需产生结果的一个对象,例程代码如下所示:# 生成器表达式方式实现生成器

print(x**2 for x in range(5))

# 打印结果:

at 0xb3d31fa4>

print(list(x**2 for x in range(5)))

# 打印结果:

[0, 1, 4, 9, 16]

通过iterrows()遍历方式计算股票每个交易日收盘价与Ma20差值,此处iterrows是对dataframe格式数据行进行迭代的一个生成器,它返回每行的索引及包含行本身的对象,代码如下所示:#iterrows()遍历方式

def iterrows_loopiter(df):

df['signal'] = 0 #df = df.assign(signal = 0) #可采用assign新增一列

for index,row in df.iterrows():

df.loc[index, 'signal'] = np.sign(row['Close']-row['Ma20'])

return df

print(iterrows_loopiter(df_stockload)[0:5])

"""

High Low Open Close Volume Adj Close Ma20 signal

Date

2018-01-29 3587.0 3510.3 3563.6 3523.0 236000 3523.0 3454.3 1.0

2018-01-30 3523.1 3484.7 3511.5 3488.0 186400 3488.0 3461.3 1.0

2018-01-31 3495.5 3454.7 3470.5 3480.8 207300 3480.8 3466.8 1.0

2018-02-01 3495.1 3424.4 3478.7 3447.0 260500 3447.0 3469.9 -1.0

2018-02-02 3463.2 3388.9 3419.2 3462.1 208100 3462.1 3473.4 -1.0

"""

apply()循环方式

apply()方法可将函数应用于dataframe特定行或列。函数由lambda方式在代码中内嵌实现,lambda 为匿名函数,可以省去定义函数的过程,让代码更加精简。lambda函数的末尾包含axis参数,用来告知Pandas将函数运用于行(axis = 1)或者列(axis = 0)。apply()方法循环方式实现的代码如下所示:df_stockload['signal'] = df_stockload.apply(lambda row: (np.sign(row['Close']-row['Ma20'])), axis = 1)

print(df_stockload.head())

"""

High Low Open Close Volume Adj Close Ma20 signal

Date

2018-01-29 3587.0 3510.3 3563.6 3523.0 236000 3523.0 3454.3 1.0

2018-01-30 3523.1 3484.7 3511.5 3488.0 186400 3488.0 3461.3 1.0

2018-01-31 3495.5 3454.7 3470.5 3480.8 207300 3480.8 3466.8 1.0

2018-02-01 3495.1 3424.4 3478.7 3447.0 260500 3447.0 3469.9 -1.0

2018-02-02 3463.2 3388.9 3419.2 3462.1 208100 3462.1 3473.4 -1.0

矢量化遍历方式

此处我们主要处理一维数组之间的计算,那么矢量化方式可使用Pandas series 的矢量化方式和Numpy arrays的矢量化方式两种。

先来看下Pandas series 的矢量化方式。

Pandas的DataFrame、series基础单元数据结构基于链表,因此可将函数在整个链表上进行矢量化操作,而不用按顺序执行每个值。

Pandas包括了非常丰富的矢量化函数库,我们可把整个series(列)作为参数传递,对整个链表进行计算。Pandas series 的矢量化方式实现代码如下:#Pandas series 的矢量化方式

df_stockload['signal'] = np.sign(df_stockload['Close']-df_stockload['Ma20'])

print(df_stockload.head())

"""

High Low Open Close Volume Adj Close Ma20 signal

Date

2018-01-29 3587.0 3510.3 3563.6 3523.0 236000 3523.0 3454.3 1.0

2018-01-30 3523.1 3484.7 3511.5 3488.0 186400 3488.0 3461.3 1.0

2018-01-31 3495.5 3454.7 3470.5 3480.8 207300 3480.8 3466.8 1.0

2018-02-01 3495.1 3424.4 3478.7 3447.0 260500 3447.0 3469.9 -1.0

2018-02-02 3463.2 3388.9 3419.2 3462.1 208100 3462.1 3473.4 -1.0

"""

对于Numpy arrays的矢量化方式,由于本例的矢量化运算中只使用了series的数值,无需使用索引等信息,因此可将series转换为array类型,节省操作过程中的很多开销。

我们可使用values 方法将链表从Pandas series转换为NumPy arrays,把NumPy array作为参数传递,对整个链表进行计算。Numpy arrays的矢量化方式实现代码如下:#Numpy arrays的矢量化方式

df_stockload['signal'] = np.sign(df_stockload['Close'].values-df_stockload['Ma20'].values)

print(df_stockload.head())

"""

High Low Open Close Volume Adj Close Ma20 signal

Date

2018-01-29 3587.0 3510.3 3563.6 3523.0 236000 3523.0 3454.3 1.0

2018-01-30 3523.1 3484.7 3511.5 3488.0 186400 3488.0 3461.3 1.0

2018-01-31 3495.5 3454.7 3470.5 3480.8 207300 3480.8 3466.8 1.0

2018-02-01 3495.1 3424.4 3478.7 3447.0 260500 3447.0 3469.9 -1.0

2018-02-02 3463.2 3388.9 3419.2 3462.1 208100 3462.1 3473.4 -1.0

"""

执行效率对比#使用timeit方法对比方法参考例程如下,需要import timeit模块:

from timeit import timeit

def test1():

forin_looping(df_stockload)

def test2():

iterrows_loopiter(df_stockload)

def test3():

df_stockload['signal'] = df_stockload.apply(lambda row: (np.sign(row['Close'] - row['Ma20'])), axis=1)

def test4():

df_stockload['signal'] = np.sign(df_stockload['Close']-df_stockload['Ma20'])

def test5():

df_stockload['signal'] = np.sign(df_stockload['Close'].values - df_stockload['Ma20'].values)

#for..in循环迭代方式

t1 = timeit('test1()', 'from __main__ import test1', number=100)

#iterrows()遍历方式

t2 = timeit('test2()', 'from __main__ import test2', number=100)

#apply()方法循环方式

t3 = timeit('test3()', 'from __main__ import test3', number=100)

#Pandas series 的矢量化方式

t4 = timeit('test4()', 'from __main__ import test4', number=100)

#Numpy arrays的矢量化方式:

t5 = timeit('test5()', 'from __main__ import test5', number=100)

print(t1,t2,t3,t4,t5)

#14.943237108999998 8.827773373 0.5511996379999999 0.02215727200000117 0.012933490000001768

总结

可以看出循环执行的速度是最慢的,iterrows()针对Pandas的dataframe进行了优化,相比直接循环有显著提升。apply()方法也是在行之间进行循环,但由于利用了类似Cython的迭代器的一系列全局优化,其效率要比iterrows高很多。

NumPy arrays的矢量化运行速度最快,其次是Pandas series矢量化。

由于矢量化是同时作用于整个序列的,可以节省更多的时间,相比使用标量操作更好,NumPy使用预编译的C代码在底层进行优化,同时也避免了Pandas series操作过程中的很多开销,例如索引、数据类型等等,因此,NumPy arrays的操作要比Pandas series快得多。

python中的df是什么意思_python df遍历的N种方式相关推荐

  1. python中如何连接两个字符串_python字符串连接的N种方式总结

    python中有很多字符串连接方式,今天在写代码,顺便总结一下: 最原始的字符串连接方式:str1 + str2 python 新字符串连接语法:str1, str2 奇怪的字符串方式:str1 st ...

  2. python中直方图bins是什么意思_Python 中下划线的 5 种含义都是什么?

    亲爱的小伙伴们 咱们8月整月开课计划已出 座位有限 感兴趣的小伙伴赶紧预约啦 建策科技8月开班计划 译者:泰然 https://dbader.org/blog/meaning-of-underscor ...

  3. python中两个集合的运算并交补_三种方式实现 Python 中的集合的交、并、补运算...

    文章目录 三种方式实现 Python 中的集合的交.并.补运算 一 背景 集合这个概念在我们高中阶段就有所了解,毕业已多年,我们一起回顾一下几个集合相关的基本概念吧? 集合是指具有某种特定性质的具体的 ...

  4. python语言format蔬菜姓名、年龄_python格式化输出的三种方式

    [TOC] 格式化输出的三种方式 一.占位符(第一种格式化输出 )(3.0版本使用) 程序中经常会出现这样的 场景:要求用户输入信息,然后打印成固定的格式 比如要求用户输入用户名和年龄,然后打印如下格 ...

  5. python中矩阵的转置怎么写_Python 矩阵转置的几种方法小结

    我就废话不多说了,直接上代码吧! #Python的matrix转置 matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] def printmatrix(m): fo ...

  6. python中的ture是常量吗_python中的true是什么

    Python的布尔类型有两个值:True和False(注意大小写要区分,首字母大写,注意) 0.逻辑运算符:a.与:and(两个都为True,结果才为True) b.或:or(只要一个为True,则为 ...

  7. python循环展示大写字母_python调用大写函数python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...

  8. python中def fun 定义函数列表_python函数

    # -*- coding:utf-8 -*- #yys #python 3.7.2 # 1.定义函数.调用函数 # 函数:组织好的.可重复使用的.用户实现单一或者关联功能的代码段. # 函数能够提高应 ...

  9. python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...

  10. python 遍历字符串的每一个字符_Python之字符串的遍历的4种方式

    python的字符串遍历有4种方式: 1. 下标法 2. for in 3. iter内置函数 4. enumerate 其中下标法和enumerate适合需要判断后续字符的场景,比如循环到下标ind ...

最新文章

  1. xgboost lightgbm catboost 多分类 多标签
  2. “AI让老百姓最多跑一次”:智源科学家打造下一代政务服务智能助手
  3. 为Drupal7.22添加富编辑器 on Ubuntu 12.04
  4. Linux系统学习----前言
  5. 经典C语言程序100例之三六
  6. 无极*压缩 之7-Zip!
  7. SAP CRM WebClient UI element id的生成逻辑
  8. 洛谷——P2018 消息传递
  9. 测试框架之testng使用
  10. 利用Python构建时间序列模型解决实际问题的正确姿势
  11. php数据类型之自动转换和强制转换
  12. vss(2005)使用详解
  13. C语言编写FFT程序
  14. IPD解读——IPD流程
  15. 数据分析常见的几种方法
  16. 一文带你了解隐私 Layer1
  17. 计算机CPU四大体系架构
  18. Ubuntu 升级显卡驱动
  19. Java虚拟机(JVM)学习合集
  20. MySQL数据库程序设计(三)

热门文章

  1. I'm coming now.
  2. LINUX最常见命令
  3. Python字符串前缀u、r、b、f含义
  4. 计算机二级考试 信息学奥赛,如何快速区分五大学科竞赛等级
  5. 图像合成——套索工具初使用
  6. mysql insert 1062_mysql insert error 1062
  7. cuda学习笔记(4)
  8. [Unity] 状态机事件流程框架 (二) 设计游戏状态的保存框架,存档功能 ScriptableObject、EasySave
  9. AlphaGo 超快棋遍虐人类高手(职业棋手讲解及大量网友评论)
  10. QQ群关键字提醒设置