1.熟悉python的基础语法,基本的编程思想,递归,迭代,贪心等,基础的算法与数据结构,这些有过编程经验的同学会比较容易理解,还有就是python的标准库,功能丰富且实用,夯实python基础,更好理解编程思想,才能愉快的开启python编程之旅。
2.既然是网络编程,那就需要学习网络方面的知识,基本的网络交互,TCP/IP协议,HTTP协议等,理解数据是如何在网络上流动的,这部分可以深入学习一下urllib这个库,试着去写几个爬虫,会对网络有更好的理解。
3.夯实了基础,有了一定的编程经验,这时候就需要学习一些框架,flask,django等web开发框架,主要学习目录设计,以及架构设计。
另外,python能做的事情很多,不只是网络编程,可以做自动化服务器运维,可以做数据分析与展现,还有现在风头正盛的AI,都是首选python做数据训练,模型优化的语言。编者,愿大家一同努力,打造中国的python社区,成长为更好的pythoner。
关于作者:Python King,Python高手大师
在使用Pandas之前,需要导入Pandas包。惯例是将pandas简写为pd,命令如下:
import pandas as pd
Pandas包含两个主要的数据结构:Series和DataFrame。其中最常用的是DataFrame,下面大家先来学习一下DataFrame。
01 DataFrame入门
DataFrame是一个表格型的数据结构。每列都可以是不同的数据类型(数值、字符串、布尔值等)。
DataFrame既有行索引也有列索引,这两种索引在DataFrame的实现上,本质上是一样的。但在使用的时候,往往是将列索引作为区分不同数据的标签。DataFrame的数据结构与SQL数据表或者Excel工作表的结构非常类似,可以很方便地互相转换。
下面先来创建一个DataFrame,一种常用的方式是使用字典,这个字典是由等长的list或者ndarray组成的,示例代码如下:
data={‘A’:[‘x’,’y’,’z’],’B’:[1000,2000,3000],’C’:[10,20,30]}df=pd.DataFrame(data,index=[‘a’,’b’,’c’])df
运行结果如图3-2所示。
▲图3-2
大家可以看到,DataFrame主要由如下三个部分组成。
数据,位于表格正中间的9个数据就是DataFrame的数据部分。索引,最左边的a、b、c是索引,代表每一行数据的标识。这里的索引是显式指定的。如果没有指定,会自动生成从0开始的数字索引。列标签,表头的A、B、C就是标签部分,代表了每一列的名称。下文列出了DataFrame函数常用的参数。其中,“类似列表”代表类似列表的形式,比如列表、元组、ndarray等。一般来说,data、index、columns这三个参数的使用频率是最高的。
data:ndarray/字典/类似列表 | DataFrame数据;数据类型可以是ndarray、嵌套列表、字典等index:索引/类似列表 | 使用的索引;默认值为range(n)columns:索引/类似列表 | 使用的列标签;默认值为range(n)dtype:dtype | 使用(强制)的数据类型;否则通过推导得出;默认值为Nonecopy:布尔值 | 从输入复制数据;默认值为False其中data的数据类型有很多种。
下文列举了可以作为data传给DataFrame函数的数据类型。
可以传给DataFrame构造器的数据:
二维ndarray:可以自行指定索引和列标签嵌套列表或者元组:类似于二维ndarray数据、列表或元组组成的字典:每个序列变成一列。所有序列长度必须相同由Series组成的字典:每个Series会成为一列。如果没有指定索引,各Series的索引会被合并另一个DataFrame:该DataFrame的索引将会被沿用前面生成了一个DataFrame,变量名为df。下面大家来查看一下df的各个属性值。
获取df数据的示例代码如下:
df.values
输出结果如下:
array([[‘x’, 1000, 10], [‘y’, 2000, 20], [‘z’, 3000, 30]], dtype=object)
获取df行索引的示例代码如下:
df.index
输出结果如下:
Index([‘a’, ‘b’, ‘c’], dtype=’object’)
获取df列索引(列标签)的示例代码如下:
df.columns
输出结果如下:
Index([‘A’, ‘B’, ‘C’], dtype=’object’)
可以看到,行索引和列标签都是Index数据类型。
创建的时候,如果指定了列标签,那么DataFrame的列也会按照指定的顺序进行排列,示例代码如下:
df=pd.DataFrame(data,columns=[‘C’,’B’,’A’],index=[‘a’,’b’,’c’])df
运行结果如图3-3所示。
▲图3-3
如果某列不存在,为其赋值,会创建一个新列。大家可以用这种方法来添加一个新的列:
df[‘D’]=10df
运行结果如图3-4所示。
▲图3-4
使用del命令可以删除列,示例代码如下:
del df[‘D’]df
运行结果如图3-5所示。
▲图3-5
添加行的一种方法是先创建一个DataFrame,然后再使用append方法,代码如下:
new_df=pd.DataFrame({‘A’:’new’,’B’:4000,’C’:40},index=[‘d’])df=df.append(new_df)df
运行结果如图3-6所示。
▲图3-6
或者也可以使用loc方法来添加行,示例代码如下:
df.loc[‘e’]=[‘new2’,5000,50]df
运行结果如图3-7所示。
▲图3-7
loc方法将在后面的内容中详细介绍。
索引的存在,使得Pandas在处理缺漏信息的时候非常灵活。下面的示例代码会新建一个DataFrame数据df2。
df2=pd.DataFrame([1,2,3,4,5],index=[‘a’,’b’,’c’,’d’,’z’],columns=[‘E’])df2
运行结果如图3-8所示。
▲图3-8
如果现在想要合并df和df2,使得df有一个新的列E,那么可以使用join方法,代码如下:
df.join(df2)
运行结果如图3-9所示。
▲图3-9
可以看到,df只接受索引已经存在的值。由于df2中没有索引e,所以是NaN值,而且df2索引为z的值已经丢失了。为了保留df2中索引为z的值,大家可以提供一个参数,告诉Pandas如何连接。示例代码如下:
df.join(df2,how=’outer’)
运行结果如图3-10所示。
▲图3-10
在上述代码中,how=’outer’表示使用两个索引中所有值的并集。连接操作的其他选项还有inner(索引的交集)、left(默认值,调用方法的对象的索引值)、right(被连接对象的索引值)等。
在金融数据分析中,大家要分析的往往是时间序列数据。下面介绍一下如何基于时间序列生成DataFrame。为了创建时间序列数据,大家需要一个时间索引。这里先生成一个DatetimeIndex对象的日期序列,代码如下:
dates=pd.date_range(‘20160101’,periods=8)dates
输出结果如下:
DatetimeIndex([‘2016-01-01’, ‘2016-01-02’, ‘2016-01-03’, ‘2016-01-04’, ‘2016-01-05’, ‘2016-01-06’, ‘2016-01-07’, ‘2016-01-08′],dtype=’da tetime64[ns]’, freq=’D’)
可以看到,使用Pandas的date_range函数生成的是一个DatetimeIndex对象。date_range函数的参数及说明如下所示:
start:字符串/日期时间 | 开始日期;默认为Noneend:字符串/日期时间 | 结束日期;默认为Noneperiods:整数/None | 如果start或者end空缺,就必须指定;从start开始,生成periods日期数据;默认为Nonefreq:dtype | 周期;默认是D,即周期为一天。也可以写成类似5H的形式,即5小时。其他的频率参数见下文tz:字符串/None | 本地化索引的时区名称normalize:布尔值 | 将start和end规范化为午夜;默认为Falsename:字符串 | 生成的索引名称date_range函数频率的参数及说明如下所示:
B:交易日C:自定义交易日(试验中)D:日历日W:每周M:每月底SM:半个月频率(15号和月底)BM:每个月份最后一个交易日CBM:自定义每个交易月MS:日历月初SMS:月初开始的半月频率(1号,15号)BMS:交易月初CBMS:自定义交易月初Q:季度末BQ:交易季度末QS:季度初BQS:交易季度初A:年末BA:交易年度末AS:年初BAS:交易年度初BH:交易小时H:小时T,min:分钟S:秒L,ms:毫秒U,us:微秒N:纳秒接下来,大家再基于dates来创建DataFrame,代码如下:
df=pd.DataFrame(np.random.randn(8,4),index=dates,columns=list(‘ABCD’))df
运行结果如图3-11所示。
▲图3-11
有了df,大家就可以使用多个基于DataFrame的内建方法了,下面来看看相关的示例。
按列求总和,代码如下:
df.sum()
输出结果如下:
A 0.241727B -0.785350C -0.547433D -1.449231dtype: float64
按列求均值,代码如下:
df.mean()
输出结果如下:
A 0.030216B -0.098169C -0.068429D -0.181154dtype: float64
按列求累计总和,代码如下:
df.cumsum()
运行结果如图3-12所示。
▲图3-12
使用describe一键生成多种统计数据,代码如下:
df.describe()
运行结果如图3-13所示。
▲图3-13
可以根据某一列的值进行排序,代码如下:
df.sort_values(‘A’)
运行结果如图3-14所示。
▲图3-14
根据索引(日期)排序(这里是倒序),代码如下:
df.sort_index(ascending=False)
运行结果如图3-15所示。
▲图3-15
选取某一列,返回的是Series对象,可以使用df.A,代码如下:
df[‘A’]
输出结果如下:
2016-01-01 -1.1423502016-01-02 -0.8161782016-01-03 0.0302062016-01-04 1.9301752016-01-05 0.5715122016-01-06 0.2204452016-01-07 0.2921762016-01-08 -0.844260Freq: D, Name: A, dtype: float64
使用[]选取某几行,代码如下:
df[0:5]
运行结果如图3-16所示。
▲图3-16
根据标签(Label)选取数据,使用的是loc方法,代码如下:
df.loc[dates[0]]
输出结果如下:
A -1.142350B -1.999351C 0.772343D -0.851840Name: 2016-01-01 00:00:00, dtype: float64
再来看两个示例代码。
df.loc[:,[‘A’,’C’]]
运行结果如图3-17所示。
▲图3-17
df.loc[‘20160102′:’20160106’,[‘A’,’C’]]
运行结果如图3-18所示。
▲图3-18
需要注意的是,如果只有一个时间点,那么返回的值是Series对象,代码如下:
df.loc[‘20160102’,[‘A’,’C’]]
输出结果如下:
A -0.816178C -0.595195Name: 2016-01-02 00:00:00, dtype: float64
如果想要获取DataFrame对象,需要使用如下命令:
df.loc[‘20160102′:’20160102’,[‘A’,’C’]]
运行结果如图3-19所示。
▲图3-19
上面介绍的是loc方法,是按标签(索引)来选取数据的。有时候,大家会希望按照DataFrame的绝对位置来获取数据,比如,如果想要获取第3行第2列的数据,但不想按标签(索引)获取,那么这时候就可以使用iloc方法。
根据位置选取数据,代码如下:
df.iloc[2]
输出结果如下:
A 0.030206B 0.759953C -1.446549D -0.874364Name: 2016-01-03 00:00:00, dtype: float64
再来看一个示例:
df.iloc[3:6,1:3]
运行结果如图3-20所示。
▲图3-20
注意:对于DataFrame数据类型,可以使用[]运算符来进行选取,这也是最符合习惯的。但是,对于工业代码,推荐使用loc、iloc等方法。因为这些方法是经过优化的,拥有更好的性能。
有时,大家需要选取满足一定条件的数据。这个时候可以使用条件表达式来选取数据。这时传给df的既不是标签,也不是绝对位置,而是布尔数组(Boolean Array)。下面来看一下示例。
例如,寻找A列中值大于0的行。首先,生成一个布尔数组,代码如下:
df.A>0
输出结果如下:
2016-01-01 False2016-01-02 False2016-01-03 True2016-01-04 True2016-01-05 True2016-01-06 True2016-01-07 True2016-01-08 FalseFreq: D, Name: A, dtype: bool
可以看到,这里生成了一个Series类型的布尔数组。可以通过这个数组来选取对应的行,代码如下:
df[df.A>0]
运行结果如图3-21所示。
▲图3-21
从结果可以看到,A列中值大于0的所有行都被选择出来了,同时也包括了BCD列。
现在大家要寻找df中所有大于0的数据,先生成一个全数组的布尔值,代码如下:
df>0
运行结果如图3-22所示。
▲图3-22
下面来看一下使用df>0选取出来的数据效果。由图3-23可以看到,大于0的数据都能显示,其他数据显示为NaN值。
df[df>0]
运行结果如图3-23所示。
▲图3-23
再来看一下如何改变df的值。首先大家为df添加新的一列E,代码如下:
df[‘E’]=0df
运行结果如图3-24所示。
▲图3-24
使用loc改变一列值,代码如下:
df.loc[:,’E’]=1df
运行结果如图3-25所示。
▲图3-25
使用loc改变单个值,代码如下:
df.loc[‘2016-01-01′,’E’] = 2df
运行结果如图3-26所示。
▲图3-26
使用loc改变一列值,代码如下:
df.loc[:,’D’] = np.array([2] * len(df))df
运行结果如图3-27所示。
▲图3-27
可以看到,使用loc的时候,x索引和y索引都必须是标签值。对于这个例子,使用日期索引明显不方便,需要输入较长的字符串,所以使用绝对位置会更好。这里可以使用混合方法,DataFrame可以使用ix来进行混合索引。比如,行索引使用绝对位置,列索引使用标签,代码如下:
df.ix[1,’E’] = 3df
运行结果如图3-28所示。
▲图3-28
ix的处理方式是,对于整数,先假设为标签索引,并进行寻找;如果找不到,就作为绝对位置索引进行寻找。所以运行效率上会稍差一些,但好处是这样操作比较方便。
对于ix的用法,需要注意如下两点。
假如索引本身就是整数类型,那么ix只会使用标签索引,而不会使用位置索引,即使没能在索引中找到相应的值(这个时候会报错)。如果索引既有整数类型,也有其他类型(比如字符串),那么ix对于整数会直接使用位置索引,但对于其他类型(比如字符串)则会使用标签索引。总的来说,除非想用混合索引,否则建议只使用loc或者iloc来进行索引,这样可以避免很多问题。
02 Series
Series类似于一维数组,由一组数据以及相关的数据标签(索引)组成。示例代码如下:
import pandas as pds=pd.Series([1,4,6,2,3])s
Out:
0 11 42 63 24 3
在这段代码中,大家首先导入pandas并命名为pd,然后向Series函数传入一个列表,生成一个Series对象。在输出Series对象的时候,左边一列是索引,右边一列是值。由于没有指定索引,因此会自动创建0到(N-1)的整数索引。也可以通过Series的values和index属性获取其值和索引。示例代码如下:
s.values
Out:
array([1, 4, 6, 2, 3], dtype=int64)
s.index
Out:
Int64Index([0, 1, 2, 3, 4], dtype=’int64′)
当然,大家也可以对索引进行定义,代码如下:
s=pd.Series([1,2,3,4],index=[‘a’,’b’,’c’,’d’])s
Out:
a 1b 2c 3d 4
在这里,大家将索引定义为a、b、c、d。这时也可以用索引来选取Series的数据,代码如下:
s[‘a’]
Out:
1
s[[‘b’,’c’]]
Out:
b 2c 3
对Series进行数据运算的时候也会保留索引。示例代码如下:
s[s>1]
Out:
b 2c 3d 4
s*3
Out:
a 3b 6c 9d 12
Series最重要的功能之一是在不同索引中对齐数据。示例代码如下:
s1=pd.Series([1,2,3],index=[‘a’,’b’,’c’])s2=pd.Series([4,5,6],index=[‘b’,’c’,’d’])s1+s2
Out:
a NaNb 6c 8d NaN
Series的索引可以通过赋值的方式直接修改,示例代码如下:
s.index
Out:
Index([u’a’, u’b’, u’c’, u’d’], dtype=’object’)
s.index=[‘w’,’x’,’y’,’z’]s.index
Out:
Index([u’w’, u’x’, u’y’, u’z’], dtype=’object’)
s
Out:
w 1x 2y 3z 4
首先是基本语法的学习,这方面可以下载《简明Python教程》学习,也可以到廖雪峰的官方网站学习。
然后,找个感兴趣的方向深入研究相关的库的使用。
Web开发方面,可以学习一下Flask和Django数据可视化方面,可以学习一下numpy、matplotlib图形界面开发方面,可以学习一下Tk、GTK+、PyQt等Python是一门非常适合用来做编程入门和科学研究的编程语言,Python语法比较简单(随意)对初学者非常友好,不过学习Python用什么IDE比较好呢?
以前Python还没有这么火,这几年伴随着人工智能越来越火,Python也越来越受到广大程序员的欢迎,自然各路商业IDE开发商和开源组织,也对Python下手了,于是越来越多的Python IDE杀出来,精品也确实不少,选择其实很多。
两款商业级IDEPython是开源的,但是Python的IDE可以非常好的商业化版本,一个是曾经拿到年度最佳开发者工具的WingIDE,一个是大名鼎鼎的JetBrains旗下的PyCharm,两款产品都做得非常好,但也都有劣势。
WingIDE拿过年度最佳开发者工具,这款集成开发环境本身也是用Python写的。早期写Python大家主要还是用Vim、Emacs、sublime text等文本编辑器,搭配插件进行开发,确实缺少好的Python IDE,WingIDE进入这个领域之后,迅速获得大批粉丝。WingIDE也有免费的社区版,用来日常学习和做作小项目绰绰有余。
PyCharm是JetBrains旗下的产品,不得不佩服JetBrains这家企业,真的是精品无数,基本上做一个工具就火一个工具,这家捷克软件公司,最初是因为两位创始人觉得当时的Java IDE都太烂了,于是就自己亲自做了大名鼎鼎的IDEA,后来就一发而不可收拾了。所以JetBrains出品必属精品,他家的IDE可以闭着眼睛用,不过使用他家的产品得是个“高富帅”,8G一下的内存就不要尝试了,不同于WingIDE 4G内容就敢尝试,PyCharm没个8G内存真不够用,毕竟这玩意儿是Java开发的。
不建议IDLE、建议VS Code都0202年了,你还没有用过VS Code的话那就真的Out啦,VS Code是微软官方做的一个开源文本编辑器,准确地说VS Code应该是介于文本编辑器和集成开发环境之间,相对于Editor功能上多了代码理解这样的功能,但又不像IDE那么臃肿。
VS Code对几乎所有主流编程语言都有着非常好的支持,当然Python也不例外,而且VS Code的第一个Python插件还是微软自己开发的。Visual Studio当然也能做Python开发,不过VS确实太庞大了,微软用一个开源的VS Code做了很多VS不能做的事情,毕竟微软想把强大的全功能VS还是藏在Windows平台上。
IDLE是Python官方的IDE,当然这款工具非常轻量级,不过吧体验是真的不太好,算不上一个很好的IDE,尤其是提示真的做得非常差,当然也能用。可是偶觉得吧,偶要是用这玩意儿,还不如继续老老实实用Emacs或者Vim,可能还舒服一点。
Matlab替代品、数据科学用Spyder前段时间哈工大被禁用Matlab的消息弄得沸沸扬扬的,尽管目前还没办法完全替代matlab,spyder倒是能够很大程度可以用来做替代品,事实上spyder这几年越来越好用了,基本上就是对标matlab发展起来的。
用Spyder你可以直接安装Anaconda,Anaconda里面的默认IDE就是Spyder,而且一切都是傻瓜式安装非常方便,不用自己的倒来倒去搞各种环境。Anaconda和Jupyter notebook已经是数据分析领域的标准工具,这个基本上已经是一个行业认知了。
Anaconda是包管理器和环境管理器,也是一个开源的Python版本,直接安装Anaconda解决一切问题,包含了conda、Python等众多科学包和依赖项,总的来说就是一个省心。Anaconda在人工智能领域也有广泛应用,Amazon首席科学家李沐、也就是《动手学深度学习》的作者,就喜欢这玩意儿。
总的来说,也看你用Python做什么,简单的学习偶主要推荐VS Code,这玩意儿确实很好用,也很强大,在StackOverflow开发者调查中,2019年最受欢迎的开发者工具中排名第一的就是VS Code,那么此时不用更待何时?