预备知识
一、Python基础
1、列表推导式与条件赋值 列表推导是(list comprehension)是一种简单的创造列表的方式,常应用于创建新的列表,其中每个元素是应用于另一个序列的每个成员或可迭代的某些操作的结果,或者创建满足特定条件的哪些元素的子序列。例如创建如下一个列表:
L=[]
def my_func(x):
return 2*x
for i in range(5):
L.append(my_func(i))
print(L)
[0, 2, 4, 6, 8]
但是,通过列表推导式,我们也可以写成
[my_func(i) for i in range(5)]
[0, 2, 4, 6, 8]
可以加上条件语句的写法,但是要注意for语句和if语句的顺序,if用来判断是对所有元素还是部分元素进行计算:
vec=[1,3,-3,5,6]
[my_func(i) for i in vec if i>0]
[2, 6, 10, 12]
[(x,y) for x in [1,2,3] for y in [3,4,5] if x!=y]
[(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5)]
另一个点是嵌套列表推导式,列表推导式中的初始表达式可以是任何表达,甚至可以是另一个列表推导式,如下对矩阵进行转置:
matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
[[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
条件赋值
带有if选择的赋值,其形式为
value=a if condition else b
val='cat'if 2>1 else 'dog'
print(val)
cat
2、匿名函数与map方法
匿名函数
有一些函数有清晰简单的映射关系,又无需在多处场合进行调用,这时候可以用匿名函数的方法简洁的表示,匿名函数用关键字lambda表示。
lambda x:2*x
[(lambda x:2*x)(i) for i in range(5)]
[0, 2, 4, 6, 8]
map函数: map()会根据提供的函数对指定序列做映射,map函数语法:
map(function,iterable,...)
function是映射方法,iterable是序列
由于python3的map()函数返回的是迭代器,所以要用list进行转换
m=map(lambda x,y:x+y,[1,2,3,4,5],[6,7,8,9,10])
print(list(m))
[7, 9, 11, 13, 15]
3、zip对象和enumerate
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
a=[1,2,3];b=[4,5,6];c=[4,5,6,7,8]
zipped=zip(a,b)
list(zipped)
a1,a2=zip(*zip(a,b))
print(a1)
(1, 2, 3)
enumerate()
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中,有点像pandas里面的sereis 。
enumerate语法 :
enumerate(sequence,[start=0])
sequence – 一个序列、迭代器或其他支持迭代对象。
start – 下标起始位置。
seasons=['spring','summer,fall','winter']
print(list(enumerate(seasons)))
print(list(enumerate(seasons,start=1)))
print()
[(0, 'spring'), (1, 'summer,fall'), (2, 'winter')]
[(1, 'spring'), (2, 'summer,fall'), (3, 'winter')]
二、Numpy基础
1、np数组的基础
array函数
numpy.array(object,dtype=None,*,copy=true,order='k',subok=False,ndmin=0)
Parameters:
object:一个数组,返回一个阵列
dtype:数据类型,可选。默认为能保存对象的最小类型
copy:布尔,可选。创建一个副本
order:{‘K’,‘A’,‘C’,“F”},可选。确定数组的顺序,只有行和列的区别,好像用的不多
subok:布尔,可选。和子类有关
ndmin:整数,可选,确定数组的维度
最常用的还是直接创建一个数组,重要的是数组的操作方法
import numpy as np
print(np.array([1,2,3]))
print(np.array([[1,2,3],[4,5,6]]))
print(np.array([1,2,3],dtype=complex,ndmin=2))
[1 2 3]
[[1 2 3]
[4 5 6]]
[[1.+0.j 2.+0.j 3.+0.j]]
i
下面讨论一些特殊数组的生成方式:
【a】:等差序列:np.linsapace,np.arrange
np.linspace
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)
num:产生的样本个数,默认是50个
endpoint:布尔型,可选,最后一个数是否包含end,默认是true
restep:布尔型,可选,如果为true,返回(samples,step)
dtype:类型,输出数组的数据类型,如果没有给出,就从其他参数推断给出
axis:整型,可选,很少用到
import numpy as np
print(np.linspace(2,3,num=5,retstep=True))
print(np.linspace(2,3,num=5,endpoint=False,retstep=True))
(array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)
(array([2. , 2.2, 2.4, 2.6, 2.8]), 0.2)
np.rrange
返回给定区间的序列,区间是半开区间[start,stop),step可选,相当于pyhon里面的range函数
np.arange([start,]stop,[stop,],dtype=nome)
step:两个邻近的值之间的距离,如果没有给定,默认值为1
dtype:类型如果没有给定,则根据其他参数来判断。
np.arange(1,5,2)
array([1, 3])
【b】特殊矩阵
zeros,eye,ones,empty,full,zeros_like,ones_like,empty_like,full_like
np.zeros(shape,dtype=float,order='c')
返回一个是给定形状和类型的全零数组
shape:新数组的形状,int or tuple of ints,(2,3)or 2
dtype:data-type,optional。default is numpy.float64
order:在内存中是以行为主,还是以列为主
np.ones,np.empty和np.zeros一样的。np.empty返回的是一个初始化为无的数组
np.eye(N,M=None,k=0,dtype=<class'float'>,order='C')
返回一个2维的对角线为1,其他地方为0的单位矩阵
N:整型,行数
M:列数,未定义时默认等于N
K:整型,可选。对角线的索引,默认值为0指的是主对角线,正数指的是上对角线,负数指的是下对角线
dtype:数据类型,返回数组的数据类型
order:默认
np.full(shape,fill_value,dtype=None,order=‘C’)
返回一个指定形状的新数组,用fill_value填充
np.zeros_like(a,dtype=None,order='k',subok=True,shape=None)
返回一个形状和类型都和a一样的0矩阵
a:array_like,一个矩阵,返回矩阵根据a来定义形状和类型
dtype:数据类型,可选。覆盖结果的数据类型
np.ones_like(a, dtype=None, order=‘K’, subok=True, shape=None)
返回一个形状和类型都和a一样的1矩阵
np.full_like(a, fill_value, dtype=None, order=‘K’, subok=True, shape=None)
返回一个形状和类型都和a一样的全fill_value矩阵
np.empty_like(prototype,dtype=none,order=‘k’,subok=True,shape=None)
返回一个形状和类型都和prototype一样的空矩阵
import numpy as np
np.zeros(5)
np.zeros(5,dtype=int)
np.zeros((2,2))
print(np.eye(3,dtype=int))
print(np.eye(5,k=1))
print(np.eye(5,6,k=-1))
print(np.ones((5,6),dtype=float))
print(np.full((2,3),9))
print(np.empty((2,3)))
[[1 0 0]
[0 1 0]
[0 0 1]]
[[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0.]
[0. 0. 0. 1. 0. 0.]]
[[1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1.]]
[[9 9 9]
[9 9 9]]
[[0. 0. 0.]
[0. 0. 0.]]
【C】随机矩阵:np.random
最常用的随机生成函数为rand,randn,randint,choice,它们分别表示0-1均匀分布的随机数组、标准正态的随机数组、随机整数组和随机列表抽样:
np.random.rand(d0,d1,d2,d3....)
返回一个指定形状的符合[0,1)之间均匀分布的随机样本,其中d,d1…dn用来指定形状
np.random.randn(d0,d1,d2,d3....,dn)
返回一个指定形状符合(0,1)之间的标准正态分布
np.random.randint(low,high=none,zize=None,dtype=int)
返回从low(闭区间)到high(开区间)的随机整数,high未定义时返回的是[0,low)
size:int or tuples of int,optionals
np.random.choice(a,size=None,replace=True,p=None)
choice 可以从给定的列表中,以一定概率和方式抽取结果,当不指定概率时为均匀采样,默认抽取方式为有放回抽样.
a:1维序列或整数。如果是一个矩阵,则从它的元素中产生样本,如果是一个数,则从np.arange(a)中产生样本
size:整型或整型元组,可选。输出的形状,默认返回单个值
replace:为True时是有放回抽样,为False时是无放回抽样
p:一维序列,可选,a中每个对应元素被抽取的概率
i
mport numpy as np
np.random.choice(10,5,replace='False')##不知道为什么replace不管用
array([2, 2, 7, 1, 2])
- np数组的变形与合并
【a】转置: T
【b】合并操作: r_, c_
对于二维数组而言, r_ 和 c_ 分别表示上下合并和左右合并:
c】维度变换: reshape
reshape 能够帮助用户把原数组按照新的维度重新排列。在使用时有两种模式,分别为 C 模式和 F 模式,分别以逐行和逐列的顺序进行填充读取。
特别地,由于被调用数组的大小是确定的, reshape 允许有一个维度存在空缺,此时只需填充-1即可:
numpy.reshape(a, newshape, order=‘C’)
ndarray.reshape是相同的方法
print(np.zeros((2,3)).T)
np.r_[np.zeros((2,3)),np.zeros((2,3))]
np.c_[np.zeros((2,3)),np.zeros((2,3))]
np.c_[np.array([0,0]),np.zeros((2,2))]
a=np.arange(12)
b=np.arange(12)
print(np.reshape(a,(3,4)))
print(b.reshape((3,4)))
print(b.reshape((2,-1)))
print(b.reshape(-1))
[[0. 0.]
[0. 0.]
[0. 0.]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
[ 0 1 2 3 4 5 6 7 8 9 10 11]
3、 np数组的切片与索引
数组的切片模式支持使用 slice 类型的 start