1.基础知识
1.1 Python基本语法
Python使用<变量名>=<表达式>的方式对变量进行赋值
(1)数据类型
字符串
字符串的定义是使用引号来定义,单引号与双引号是等价的
三引号用来输入包含多行文字的字符串
1 2 3 4
| s='''hello my world''' print(s)
|
hello
my
world
字符串的加法
1 2 3
| a="hello " b="world" a+b
|
'hello world'
字符串的索引
1 2
| c="hello world" c[0]+c[5]+c[6]
|
'h w'
字符串的分割 split
['hello', 'world']
1 2
| e='hello,world' e.split(',')
|
['hello', 'world']
查看字符串的长度 len
11
整数
浮点数
布尔值
True
False
空值
''
(2)运算符
运算符:http:www.runoob.com/phthon/python-operators.html#ysf4
基本运算
**:幂运算
/:除以
%:取模-返回余数
//:取整除-返回商的整数部分(向下取整)
比较运算
==,!=,<>,>,<,>=,<=
赋值运算
=,+=,-=,=,/=,%=,*=,//=
逻辑运算
&,|,not
False
(3)数据结构
列表 list
Python用 [] 来生成列表,也可以用 list 关键字
[1, 2.3, '哈哈']
['a', 'b', 'c', 'd', 'e']
列表操作
列表常用函数:https://www.cnblogs.com/smelond/p/7857701.html
1 2 3 4
| a=[1,2,3] b=['张三','李四'] a+b
|
[1, 2, 3, '张三', '李四']
1 2 3
| c=[1, 2, 3, '张三', '李四'] c[0]
|
1
[1, 2, 3, 1.001, '张三', '李四', '王五']
1 2 3 4
| e=c e.insert(3,1.001) e
|
[1, 2, 3, 1.001, '张三', '李四', '王五', '王五', '王五']
[1, 2, 3, '张三', '李四', '王五']
[2, 3, '张三']
[1, 2, 3, '张三']
[1, 2, 3, '张三', '李四', '王五']
[2, 3, '张三', '李四']
[1, 3, '李四']
['王五', '张三', 2]
1 2 3
| h=[1, 2, 3, '张三', '李四'] 4 not in h
|
True
元组 tuple
另一种有序列表叫元组,用 () 来表示。tuple和list非常类似,但是tuple一旦初始化就不能修改
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-65-d047ecce1dea> in <module>
1 a=(1,2,3,4,5)
----> 2 a.pop()
AttributeError: 'tuple' object has no attribute 'pop'
字典 dict
用 {key:value} 的形式来生成字典
字典里面的数据可以是任何数据类型,也可以是字典
1 2 3 4 5
| mv={'name':'肖申克的救赎', 'actor':'罗宾斯', 'score':9.6, 'country':'USA'} mv
|
{'name': '肖申克的救赎', 'actor': '罗宾斯', 'score': 9.6, 'country': 'USA'}
'罗宾斯'
dict_keys(['name', 'actor', 'score', 'country'])
dict_values(['肖申克的救赎', '罗宾斯', 9.6, 'USA'])
dict_items([('name', '肖申克的救赎'), ('actor', '罗宾斯'), ('score', 9.6), ('country', 'USA')])
1 2 3
| mv['name']='泰坦尼克号' mv['actor']='小李子' mv.items()
|
dict_items([('name', '泰坦尼克号'), ('actor', '小李子'), ('score', 9.6), ('country', 'USA')])
1 2
| mv['director']='德拉邦特' mv
|
{'name': '泰坦尼克号',
'actor': '小李子',
'score': 9.6,
'country': 'USA',
'director': '德拉邦特'}
{'name': '泰坦尼克号', 'actor': '小李子', 'score': 9.6, 'director': '德拉邦特'}
集合 set
用 {} 来生成集合,集合中不含有相同的元素
{2, 3, 4, 5}
4
{1, 2, 3, 4, 5}
{2, 3, 4}
{1, 2, 3, 4, 5, 7, 8}
{1, 5}
可变对象和不可变对象
可变对象可以对其进行插入,删除等操作,不可变对象不可以对其进行有改变的操作。Python中列表、字典、集合都是可变的。元组、字符串、整型等都是不可变的。
(4)类型转换
3
2.0
str
['a', 'b', 'c', 'd']
(5)判断和循环
判断
True
False
False
1 2 3 4
| if 2<1: print("yes") else: print('no')
|
no
1 2 3 4 5 6 7
| for i in range(5): if i==3: print(i,'等于3') elif i>3: print(i,'大于3') else: print(str(i)+'小于3')
|
0小于3
1小于3
2小于3
3 等于3
4 大于3
循环
1 2
| for i in [1,2,3,4,5]: print(i)
|
1
2
3
4
5
1 2 3 4
| i=1 while i<7: print(i) i+=1
|
1
2
3
4
5
6
(6)列表生成式
列表生成式及List Comprehensions,是Python内置的非常简答却强大的可以用来创建list的生成式
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1
| [x**2 for x in range(1,10)]
|
[1, 4, 9, 16, 25, 36, 49, 64, 81]
1
| [i for i in range(1,100) if i%10==0]
|
[10, 20, 30, 40, 50, 60, 70, 80, 90]
1
| [str(i) for i in range(5)]
|
['0', '1', '2', '3', '4']
1
| [int(x) for x in list('123456')]
|
[1, 2, 3, 4, 5, 6]
1.2 Python函数
(1)内置函数
内置函数:https://www.runoob.com/python/python-built-in-functions.html
1
1 2 3
| a=[2,3,5,7,23,-45,43] max(a)
|
43
-45
38
(2)自定义函数
Python函数:https://www.runoob.com/python/python-functions.html
函数function,通常接受输入参数,并有返回值。
它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。
函数通常有几个特性:
1、使用def关键词来定义一个函数
2、def后面是函数的名称,括号中是函数的参数,不同的参数用逗号,隔开,def func(): 的形式是必须要有的,参数可以为空
3、使用缩进来划分函数的内容
4、return返回特定的值,如果省略,返回None
1 2 3
| def add_two(x,y): return x+y add_two(1,2)
|
3
使用函数时,只需要将参数换成特定的值传给函数
Python并没有限定参数的类型,因此可以使用不同的参数类型
如果传入的两个参数不能做运算,或者传入的参数的数目与实际不符,python都会报错
可以在函数定义的时候给参数设定默认值
1 2 3
| def func1(x,a=1,b=2,c=3): return x*a+x*b+x*c func1(5)
|
30
一个函数可以返回多个返回值(元组)
1 2 3
| def func2(x): return x**2,x**3 func2(2)
|
(4, 8)
2.第三方库NumPy
https://www.runoob.com/numpy
NumPy是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多。
NumPy(Numeric Python)提供了许多高级的数值编程工具。Numpy的一个重要特征是它的数组计算,是我们做数据分析必不可少的一个包。
导入Python库使用关键字import,后面可以自定义库的简称,但是一般都将NumPy命名为np,pandas命名为pd。
使用前一定要先导入Numpy包,导入的方法有以下几种:
import numpy
import numpy as np
from numpy import * ##不用加前缀,但和其他包函数重名容易报错
1.1Numpy的数组对象及其索引
数组上的数学操作
假如我们想将列表中的每个元素增加1,但列表不支持这样的操作:
1 2
| a=[1,2,3,4] [i+1 for i in a]
|
[2, 3, 4, 5]
与另一个数相加,得到对应元素相加的结果:
1 2 3
| a=[1,2,3,4] b=[2,3,4,5] [x+y for (x,y) in zip(a,b)]
|
[3, 5, 7, 9]
这样的操作比较麻烦,而且在数据量特别大的时候会非常耗时间。
如果我们使用Numpy,就会变得特别简单
1 2 3
| a=np.array([1,2,3,4]) b=np.array([2,3,4,5]) a+1
|
array([2, 3, 4, 5])
array([3, 5, 7, 9])
产生数组 array
从列表产生数据
1 2 3
| l=[0,1,2,3] a=np.array(l) a
|
array([0, 1, 2, 3])
从列表传入
array([1, 2, 3, 4])
生成全0数组
array([0., 0., 0., 0., 0.])
生成全1数组
1 2
| a=np.ones(5,dtype='bool') a
|
array([ True, True, True, True, True])
可以使用fill方法将数组设定为指定值
与列表不同,数组中要求所有元素的dtype是一样的,如果传入参数的类型与数组类型不一样,需要按照已有的类型进行转换。
1 2 3
| a=np.array([1,2,3,4]) a.fill(2.5) a
|
array([2, 2, 2, 2])
1 2 3 4 5
| a=np.array([1,2,3,4]) a=a.astype('float') a.fill(2.5) a
|
array([2.5, 2.5, 2.5, 2.5])
使用特定的方法生成特殊的数组
生成整数序列 arange
array([1, 3, 5, 7, 9])
生成等差数列 linspace
1 2
| a=np.linspace(1,19,10) a
|
array([ 1., 3., 5., 7., 9., 11., 13., 15., 17., 19.])
生成随机数 random.rand/randn
array([0.17321107, 0.99373562, 0.3975442 , 0.70928465, 0.94911133,
0.42808941, 0.63640154, 0.79841176, 0.13196705, 0.94727648])
1 2
| b=np.random.randn(10) b
|
array([-0.08383046, 0.63174363, 2.39860083, 0.38896599, 2.15220553,
-0.07221372, -0.05394666, -1.37264763, 1.48804014, 1.22077146])
1 2
| c=np.random.randint(1,10,10) c
|
array([2, 7, 6, 8, 2, 5, 6, 3, 8, 3])
数组属性
查看类型
1 2
| a=np.array([1,2,3,4]) type(a)
|
numpy.ndarray
查看数组中的数据类型
dtype('int32')
查看形状,会返回一个元组,每个元素代表这一堆的元素数目
(4,)
查看数组里面元素的数目
4
查看数组的维度
1
索引与切片
索引第一个元素
1 2
| a=np.array([1,2,3,4]) a[0]
|
1
修改第一个元素的值
array([10, 2, 3, 4])
切片,支持负索引
1 2
| a=np.array([11,12,13,14,15]) a[1:3]
|
array([12, 13])
array([12, 13])
省略参数
1 2
| a=np.array([11,12,13,14,15]) a[-2:]
|
array([14, 15])
array([11, 13, 15])
错位相减
1 2 3 4
| b=np.array([11,25,46,58,76]) b1=b[1:] b2=b[:-1] b1-b2
|
array([14, 21, 12, 18])
多维数组
多维数组及其属性
将以列表为元素的列表传入,最终得到的额就是一个二维数组
1 2
| a=np.array([[1,2,3,4],[5,6,7,8]]) a
|
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
查看形状
(2, 4)
查看总的元素个数
8
查看维数
2
多维数组索引
对于二维数组,可以传入两个数字来索引
1 2
| a=np.array([[1,2,3,4],[5,6,7,8]]) a
|
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
8
索引赋值
array([[1, 2, 3, 4],
[5, 6, 7, 9]])
索引一整行内容
array([5, 6, 7, 9])
Python会将这单个元组当成对第一堆的索引,然后返回对应的内容
行索引在逗号前,列索引在逗号后
array([2, 6])
多维数组切片
1 2
| a=np.array([[0,1,2,3,4,5],[10,11,12,13,14,15],[20,21,22,23,24,25],[30,31,32,33,34,35],[40,41,42,43,44,45],[50,51,52,53,54,55]]) a
|
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
取到第一行的第4和第5两个元素
array([3, 4])
得到最后两行的最后两列
array([[44, 45],
[54, 55]])
得到第3列
array([ 2, 12, 22, 32, 42, 52])
每一堆都支持切片的规则,包括负索引,省略
[lower:upper:step]
array([[20, 22, 24],
[40, 42, 44]])
切片是引用
切片在内存中使用的是引用机制。
引用机制意味着,Python并没有为b分配新的空间来存储它的值,而实让b指向了a所分配的内存空间,因此,改变b会改变a的值。
1 2 3
| a=np.array([0,1,2,3,4]) b=a[2:4] b
|
array([2, 3])
array([ 0, 1, 10, 3, 4])
而这种现象在列表中并不会出现
1 2 3
| list=[1,2,3,4,5] list1=list[2:4] list1
|
[3, 4]
[1, 2, 3, 4, 5]
这样的好处在于,对于很大的数据,不用大量复制多余的值,节约了空间
缺点在于,可能出现改变一个值而改变另一个值的情况。
一个解决方法是使用copy()方法产生一个复制,这个复制中会申请新的内存。
1 2 3 4
| a=np.array([0,1,2,3,4]) b=a[2:4].copy() b[0]=10 a
|
array([0, 1, 2, 3, 4])
花式索引
切片只能支撑连续或者等间隔的切片操作,要想实现任意位置的操作,需要使用花式索引 fancy slicing
一维花式索引
与range函数类似,我们可以使用arange函数来产生等差数组
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
花式索引需要指定索引位置
1 2 3
| index=[1,2,-3] y=a[index] y
|
array([10, 20, 70])
还可以使用布尔数组来花式索引
1 2
| mask=np.array([0,2,2,0,0,1,0,0,1,0],dtype=bool) mask
|
array([False, True, True, False, False, True, False, False, True,
False])
array([10, 20, 50, 80])
mask必须是布尔数组,长度必须和数组长度相等
二维花式索引
对于二维花式索引,我们需要给定行和列的值
1 2
| a=np.array([[0,1,2,3,4,5],[10,11,12,13,14,15],[20,21,22,23,24,25],[30,31,32,33,34,35],[40,41,42,43,44,45],[50,51,52,53,54,55]]) a
|
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45],
[50, 51, 52, 53, 54, 55]])
返回的是一条次对角线上的5个值(此处取1,12,23,34,45)
1
| a[(0,1,2,3,4),(1,2,3,4,5)]
|
array([ 1, 12, 23, 34, 45])
返回最后三行的1,3,5列
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
使用布尔数组进行索引
1 2
| mask=np.array([1,0,1,0,1,0],dtype=bool) a[-3:,mask]
|
array([[30, 32, 34],
[40, 42, 44],
[50, 52, 54]])
与切片不同,花式索引返回的是对象的一个复制而不是引用
“不完全”索引
只给定行索引的时候,返回整行
1 2 3
| a=np.array([[0,1,2,3,4,5],[10,11,12,13,14,15],[20,21,22,23,24,25],[30,31,32,33,34,35],[40,41,42,43,44,45],[50,51,52,53,54,55]]) y=a[:3] y
|
array([[ 0, 1, 2, 3, 4, 5],
[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25]])
这时候也可以使用花式索引取出2,3,5行
1 2
| con=np.array([0,1,1,0,1,0],dtype=bool) a[con]
|
array([[10, 11, 12, 13, 14, 15],
[20, 21, 22, 23, 24, 25],
[40, 41, 42, 43, 44, 45]])
where语句
where(array)
where函数会返回所有非零元素的索引
1 2
| a=np.random.randint(1,10,10) a
|
array([1, 2, 3, 3, 7, 6, 7, 8, 3, 4])
(array([4, 5, 6, 7], dtype=int64),)
array([0, 0, 0, 0, 1, 1, 1, 1, 0, 0])
一维数组
判断句数组中的元素是不是大于10
array([False, True, False, True])
数组中所有大于10的元素的索引位置
(array([1, 3], dtype=int64),)
注意到where的返回值是一个元组,返回的是索引位置
也可以直接用数组操作
array([12, 20])
array([12, 20])
1.2数组类型
数组类型
布尔型:bool:占一个字节
整型:int8/16/32/64/128,int:和C语言的long一样大
无符号整型:uint8/16/32/64/128,uint:和C语言中的unsigned long一样大
浮点数:float16/32/64,float,longfloat:默认为双精度float64,longfloat精度大小与系统有关
复数:complex64/128,complex,longconplex:默认为complex128,即实部虚部都为双精度
字符串:string,unicode:可以使用表示一个4字节字符串的数组
对象:object:数组中可以使用任意值
时间:datetime64,timedelta64
类型转换
1 2
| a=np.array([1.5,-3],dtype=int) a
|
array([ 1, -3])
asarray函数
1 2
| a=np.array([1,2,3]) np.asarray(a,dtype=float)
|
array([1., 2., 3.])
astype函数
1 2 3
| a=np.array([1,2,3]) a.astype(float)
|
array([1., 2., 3.])
1 2 3 4
| a=np.array([1,2,3]) b=a.astype(float) b[0]=0.5 b
|
array([0.5, 2. , 3. ])
array([1, 2, 3])
astype引用不会对原数组产生影响
1.3 数组操作
以豆瓣10部高分电影为例
1 2
| mv_name=['肖申克的救赎','控方证人','美丽人生','阿甘正传','霸王别姬','泰坦尼克号','辛德勒的名单','这个杀手不太冷','疯狂动物成','海豚湾']
|
1 2
| mv_num=np.array([692795,42995,327855,580897,478523,157074,306904,662552,284652,159302])
|
1 2
| mv_score=np.array([9.6,9.5,9.5,9.4,9.4,9.4,9.4,9.3,9.3,9.3])
|
1 2
| mv_length=np.array([142,116,116,142,171,194,195,133,109,92])
|
数组排序
sort函数
array([ 42995, 157074, 159302, 284652, 306904, 327855, 478523, 580897,
662552, 692795])
array([692795, 42995, 327855, 580897, 478523, 157074, 306904, 662552,
284652, 159302])
argsort函数
argsort返回从小到大的排列在数组中的索引位置
1 2
| order=np.argsort(mv_num) order
|
array([1, 5, 9, 8, 6, 2, 4, 3, 7, 0], dtype=int64)
1
'控方证人'
数学操作
求和
3693549
3693549
最大值
195
195
最小值 min
均值 mean
标准差 std
方差 var
相关系数矩阵 cov
1
| np.cov(mv_score,mv_length)
|
array([[9.88888889e-03, 4.55555556e-01],
[4.55555556e-01, 1.26288889e+03]])
多维数组操作
数组形状 shape
array([0, 1, 2, 3, 4, 5])
array([[0, 1, 2],
[3, 4, 5]])
(2, 3)
与之对应的方法是reshape,但它不会改变原来数组的值,而是返回一个新的数组
array([0, 1, 2, 3, 4, 5])
array([[0, 1, 2],
[3, 4, 5]])
array([0, 1, 2, 3, 4, 5])
转置 T/transpose
array([[0, 1, 2],
[3, 4, 5]])
array([[0, 3],
[1, 4],
[2, 5]])
array([[0, 3],
[1, 4],
[2, 5]])
数组连接
concatenate((a0,a1,…,an),axis=0)
axis=0代表往跨行(down),而axis=1代表跨列(across)
使用0值表示沿着每一列或行标签\索引值向下执行方法
使用1值表示沿着每一行或者列标签模向执行对应的方法
注意:这些数组要用()包括到一个元组中去。
除了给定的轴外,这些数组其他轴的长度必须是一样的。
1 2 3
| x=np.array([[0,1,2],[10,11,12]]) y=np.array([[50,51,51],[60,61,62]]) print(x.shape,y.shape)
|
(2, 3) (2, 3)
默认沿着第一维进行连接
1 2
| z=np.concatenate((x,y),axis=0) z
|
array([[ 0, 1, 2],
[10, 11, 12],
[50, 51, 51],
[60, 61, 62]])
沿着第二维进行连接
1 2
| z=np.concatenate((x,y),axis=1) z
|
array([[ 0, 1, 2, 50, 51, 51],
[10, 11, 12, 60, 61, 62]])
注意到这里x和y的形状是一样的,还可以将它们连接成三维的数组,但是concatenate不提供这样的功能,可以这样操作:
array([[[ 0, 1, 2],
[10, 11, 12]],
[[50, 51, 51],
[60, 61, 62]]])
事实上,NumPy提供了分别对应这三种情况的函数
vstack
array([[ 0, 1, 2],
[10, 11, 12],
[50, 51, 51],
[60, 61, 62]])
hstack
array([[ 0, 1, 2, 50, 51, 51],
[10, 11, 12, 60, 61, 62]])
dstack
array([[[ 0, 50],
[ 1, 51],
[ 2, 51]],
[[10, 60],
[11, 61],
[12, 62]]])
1.4 NumPy内置函数
https://blog.csdn.net/nihaoxiaocui/article/details/51992860
array([1, 2, 3, 2])
array([ 0.36787944, 7.3890561 , 20.08553692, 0.13533528])
0.5
array([-1, 1, 4, 2], dtype=int32)
感谢鼓励