numpy的介绍
numpy是一个python开源的科学计算库
使用numpy可以方便的使用数组、矩阵(列表套列表)进行计算
包括线性代数、傅里叶变换,随机数生成等大量函数
python源代码和numpy和的区别
import numpy as np
def func(n):
a = np.arange(n) **2
b = np.arange(n) **3
return a+b
print(func(10))
# python原生代码
def func(n):
a = [i**2 for i in range(n)]
b = [i**3 for i in range(n)]
num_ab = []
for i in range(n):
num_ab.append(a[i]+b[i])
return num_ab
print(func(10)
创建数组和参数介绍
numpy.array(object, dtype = None, copy = True, order = None,subok=False,ndmin = 0)
object 表示一个数组序列。 (可以是数组或元组)
dtype 可选参数,通过它可以更改数组的数据类型 (dtype='int')
copy 可选参数,当数据源是ndarray时表示数组能否被复制,默认是 True。
# 复制之后 重新申请了一份内存地址 修改b的内存地址 并不会影响a的内存地址
order 可选参数,以哪种内存布局创建数组,有3个可选值,分别是 C(行序列)/F(列序列)/A(默认)。
ndmin 可选参数,用于指定数组的维度。
subok 可选参数,类型为bool值,默认False。为True,使用object的内部数据类型;False:使用object数组的数据类型。
# 数组介绍
一维数组 [1,2,3,2,3]
二维数组 [[1,5,6,8,],[45,485,4,85]]
三维数组 [1,23,[1,2[,4,5]],[1,12[4,4,5]]]
numpy可以使用生成器和类型转换成数组
import numpy as np
res = np.array([i//2!=0 for i in range(10)])
print(res)
res.ndim # 可以查看是几维的
# 默认转换 强制转换 dtype = n
# 列表中元素不相同
res = np.array([1,2,2,3,'5'])
print(res) # ['1','2','2','3','5'] 全部转为字符串
# 整形
res = array.([i for i in range(10)])
print(res) # [0,1,2,3,4,5,6,7,8,9]
# 浮点型 数组里面有浮点型 则全部转为浮点型
# 如果强制转换成整形 则没有四舍五入 直接取整数
res = array.([1,1.2,3,3.14,])
# 二维数组 可以是数组 可以是元组
res = ([[1,2,3,3],('a','b','c','d')])
print(res) [['1','2','3'],['a','b','c','d']]
# 如果嵌套数量不一样的情况下 会变成一维
res = ([[1,2,3,3],('a','b','c','d')])
print(res) [(['1','2','3']),(['a','b','c','d'])]
numpy.arange生成区间数组
根据start和stop指定的范围和step设定的步长 生成一个ndarray
import numpy
res = numpu.arange(start,stop,step,dtype)
# 参数介绍:
start 起始值 默认为0(包含起始值) 顾头不顾尾
stop 结束值 自定义(不包含介绍值)
step 步长
dtype 返回ndarray数据类型 如果没有提供 则默认使用传入的数据类型
res = np.arange(20,step=3) # 如果只传两个 第二个需要指定参数
linspace() 创建等差数列
'''
返回在间隔[开始,停止]上计算的num个均匀间隔的样本。数组是一个等差数列构成np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)参数说明
'''
参数说明:
start 必填项,序列的起始值,
stop 必填项,序列的终止值,如果endpoint为true,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中包含stop值,反之不包含,默认是True.
retstep 如果为 True 时,生成的数组中会显示间距,反之不显示。
dtype ndarray 的数据类型
# 1 到 10 之间 num就是分多少个值
res = np.linspace(1,10,10) # 顾头也顾尾
res
# array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
res = np.linspace(1,10,9) # 顾头也顾尾
res
# array([ 1. , 2.125, 3.25 , 4.375, 5.5 , 6.625, 7.75 , 8.875,10. ])
# 如果不包含终止值 endpoint=False
res = np.linspace(3,10,9,endpoint=False)
# 显示步长 retstep=True
res = np.linspace(3,10,9,endpoint=False,retstep=True)
logspace等比数列
'''
返回在间隔[开始,停止]上计算的num个均匀间隔的样本。数组是一个等比数列构成np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
'''
参数介绍
start 必填项,序列的起始值,
stop 必填项,序列的终止值,如果endpoint为true,该值包含于数列中
num 要生成的等步长的样本数量,默认为50
endpoint 该值为 true 时,数列中包含stop值,反之不包含,默认是True.
base 对数 log 的底数 base=次方
dtype ndarray 的数据类型
res = np.logspace(1,10,10,base=2)
res
# 一到十 分成十份 等到的数字*2的平方
# 练习题:
"""
一个穷人到富人那里去借钱,原以为富人不愿意,哪知富人一口答应了下来,但提出了如下条件:
1、在30天中,富人第一天借给穷人1万元,第二天借给2万,以后每天所借的钱数都比上一天的多一万;
2、但 借钱第一天,穷人还1分钱,第二天还2分钱,以后每天所还的钱数都是上一天的两倍。
3、思考下,如何用我们刚才学到的方法计算出结果,确定是否向富人借钱?
"""
全0数列 numpy.zeros 和全1数列numpy.ones
"""
创建指定大小的数组,数组元素以0来填充numpy.zeros(shape, dtype = float, order = 'C')
参数说明
"""
shape 数组形状
dtype 数据类型,可选
NumPy数组属性
NumPy 的数组中比较重要 ndarray 对象属性有:
ndarray.ndim 秩,即轴的数量或维度的数量(几维度)
ndarray.shape 数组的维度,对于矩阵,n行m列()
ndarray.size 数组元素的总个数,相当于.shape 中 n'm 的值
ndarray.dtype ndarray对象的元素类型
ndarray.itemsize ndarray 对象中每个元素的大小,以字节为单位
1、 ndarray.shape 计算维度 列与行
返回一个包含数组维度的元组,对于矩阵,n行m列,它也可以用于调整数组维度
a= np.array([1,2,3,4,5,6])
print('一维数组:',a.shape)
# 一维数组: (6,) 打印的是数组内的元素
b= np.array([[1,2,3],[4,5,6]])
print('二维数组:',b.shape)
# 二维数组: (2, 3) 二维数组 里面有 2行3列
c = np.array([
[[1,2,3],[4,5,6]],
[[11,22,33],[44,55,66]]
])
print('三维数组',c.shape) # 三维数组 (2, 2, 3) 两个大列里面有两个小列 和三行
2. 调整维度 reshape
返回调整维度之后的副本 而不改变 ndarray
res = np.arange(0,20).reshape((4,5)) 只能整除 变成二维
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
# 实例:
res = np.array([1,2,3,4,5,6])
print('a的形状',a.shape)
print('a',a)
# 使用数组A 创建一个数组b 并且修改维度
b = a.reshape((2,3))
print('b的形状',b.shape)
print('b',b)
a的形状 (6,) 一维元素个数
a [1 2 3 4 5 6]
b的形状 (2, 3) 二维的列与行
b [[1 2 3]
[4 5 6]]
# 错误示范
res = np.arange(0,20).reshape((4,6))
# resize 修改维度的时候不够 则用0来填充 需要加上参数 refcheck=False
a=np. array([[0,1],[2,3]])
#a为原数组创建2行3列的新数组
b_2_3=np.resize(a,(3,4))
array([[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]])
a.resize((3,4),refcheck=False)
array([[0, 1, 2, 3],
[0, 0, 0, 0],
[0, 0, 0, 0]])
# numpy数据类型转换,调用astype返回数据类型修改后的数据,但是源数据的类型不会变
# 查看数据类型大小 字节为单位 ndarray.itemsize
res = np.array([11,22,33,44,55])
print(res.itemsize) # 4 元素字节的大小 而不是全部元素
数组创建图片展示
数组属性展示图
切片和索引
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中list 的切片操作一样。
ndarray 数组可以基于0-n的下标进行索引
注意:区别在于数组切片是原始数组视图(这就意味着,如果做任何修改,原始都会跟着更改)。这也意味着,如果不想更改原始数组,我们需要进行显式的复制,从而得到它的副本(.copy())。 copy重新申请一块内存空间
索引取值 (一维取值)
import numpy as np
res = np.arange(10) # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
res1 = res[2:7:2] # 从索引位置2开始 到7的位置 步长为2
res1[2] # 6
res1[-1] # 负数就是从后往前取值
"""
冒号的解释:
如 [2],将返回与该索引相对应的单个元素。
如果为[2:],表示从该索引开始以后的所有项都将被提取。
如果使用了两个参数,如[2:7],那么则提取两个索引(不包括停止索引)之间的项。
如果使用了两个参数,如 [:7] 默认从0开始 到索引位置
res1 = res[::2] # 从索引位置开始 到结束的位置 步长为2
"""
二维数组取值
import numpy as np
res = np.arange(1,21).reshape((4,5))
res
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
res1 = res[3][4]
res1 # 20
res1 = res[:2][1]
red # array([ 6, 7, 8, 9, 10])
# 进行列取值
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
res2 = res[...,2] # ... 代表所有列
res2 # array([ 3, 8, 13, 18])
res = [...,1:]
array([[ 3, 4, 5],
[ 8, 9, 10],
[13, 14, 15],
[18, 19, 20]])
# 返回2行3列的数据 两种方式
res = [1,2] # 去出第一列的第 三个
res1 = res[1][2] # 虽然值相同 但是取值方式不一样
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
res4 = res[[1,2,3],[1,2,2]]
res4 # array([ 7, 13, 18])
# 取出来的是一个一维的
"""
解释:第一个数组取的是行 第二个数组取的是列
1行 1列
2行 2列
3行 2列
"""
# 去出来之后 可以转换成二维的
res = np.arange(1,21).reshape((4,5))
r = np. array([[0,0],[3,3]]).reshape(4)
l = np. array([[0,2],[0,2]]).reshape (4)
s = res[r, l].reshape((2,2))
s
# 行跟列也可以切片
res = np.arange(1,21).reshape((4,5))
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]])
#行取得2行和3行,列取得2列和3列
b= res[1:3,1:3] # res[[l,2], [l,2]]
# 1:3 == [1,2]
b
# 练习
res = np.zeros(8*8,dtype='int').reshape((8,8))
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
res[0::2,::2] = 1 # 第一个代表的是行 第二个代表的是列
res[1::2,1::2] = 1
res
# 结果
array([[0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0]])
2.布尔数组索引和 and和or
当输出的结果需要经过布尔运算(如比较运算)时,此时会使用到另一种高级索引方式,即布尔数组索引。下面示例返回数组中大于6的的所有元素:
布尔索引 实现的是通过一维数组中的每个元素的布尔型数值对一个与一维数组有着同样行数或列数的矩阵进行符合匹配。这
种作用,其实是把一维数组中布尔值为True的相应行或列给抽取了出来
注意:一维数组的必须和想要切片的维度和轴必须一至
##返回所有大于6的数字组成的数组
x=np.array([[0,1,2],[3,4,5],[6,7,8],[ 9,10, 11]])
x.ndim # 二维数组也是
x[x>6] # array([ 7, 8, 9, 10, 11])
# 练习题·
1.提取出数组中所有奇数
2.修改奇数值修改为-1
x=np.array([[0,1,2],[3,4,5],[6,7,8],[ 9,10, 11]]).reshape((3,4))
x[0::1,0::2] = -1
x
# 筛选出指定区间内数据
&和
|或
x=np.array([[0,1,2],[3,4,5],[6,7,8],[9, 10,11]])#以上x中大于4并且小于9的数据x[(x>4) & (x<9)]
x=np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])
#以上x中小于4或者大于9的数据
x[(x<4) | (x>9)]
True和False的形式表示需要和不需要的数据 但是要与数据行或者列对应
a3 = np.arange(12).reshape((3,4))
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
#行变量 存在3个元素
rowl = np.array([False, True, True])
#列变量存在4个元素
columnl = np.array([True, False, True, False])
a3[[False, True, True], [True, False, True, False]]
跟 a3[[1,2],[1,2]] 一样的
广播机制
"""
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式,对数组的算术运算通常在相应的元素上进行。
如果两个数组a和b形状相同,即满足 a.shape == b.shape,那么 a*b的结果就是a与b数组对应位相乘。这要求维数相同,且各维度的长度相同。
"""
a = np.array([1,2,3,4])
b= np. array([10,20,30,40])
c=a*b
print(c)
"""
但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?当然不是!为了保持数组形状相同
NumPy 设计了一种广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。
"""
a=np.array([[0,0,0],[10, 10, 10].[20,20, 20],[30, 30, 30]])
b = np.array([1,2,3])
print(a + b)
"""
广播的规则:
让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加1补齐。
输出数组的形状是输入数组形状的各个维度上的最大值。(# 以最大维度为标准)
(可以相加的前提条件 要么维度的值相同 要么是值为1才行)
当输入数组的某个维度的长度为1时,沿着此维度运算时都用此维度上的第一组值。
如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为1时,这个数组能够用来计算,否则出错。
如下:
两个数组右对齐以后,对应维度里的数值要么相等,要么为1,要么缺失、取大值。
除此之外就会报错。像下面的两个数组就不能做运算。
数组a大小为(2,1,3)
数组b大小为(4,2)首先右对齐:
2 1 3
4 2
2跟3不匹配,此时就不能做运算 报错
# 对于广播规则另一种简单理解
将两个数组的维度大小右对齐,然后比较对应维度上的数值
如果数值相等或其中有一个为1或者为空,则能进行广播运算
输出的维度大小为取数值大的数值。否则不能进行数组运算。
"""
索引和切片的总结
函数统计
NumPy能方便的求出统计出常见的描述性统计量 (内置函数)
求平均值
import numpy as np
res = np.arange(0,20).reshape((4,5))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
print(res)
res.mean() # 9.5
mean(axis=0)
# 0 代表的是列除array([ 7.5, 8.5, 9.5, 10.5, 11.5])
# 1 代表的是行除 array([ 2., 7., 12., 17.])
中位数 np.median
"""
又称中点数,中值
是按顺序排列的一组数据中居于中间位置的数,代表一个样本、种群或概率分布中的一个数值
平均数:是一个"虚拟"的数,是通过计算得到的,它不是数据中的原始数据.中位数:是一个不完全"虚拟"的数。
平均数:反映了一组数据的平均大小,常用来一代表数据的总体"平均水平".中位数:像一条分界线,将数据分成前半部分和后半部分,因此用来代表一组数据的"中等水平"
如果是奇数 则会取中间值
如果是偶数 则是中间的两个值相加再除以2 得到的就是中间值
"""
# 奇数
res = np.array([1,2,3,4,5])
np.median(res) # 3.0
# 偶数
res = np.array([1,2,3,4,5,6])
np.median(res) # 3.5
标准差 np.std()
简单来说,标准差是一组数据平均值分散程度的一种度量,
一个较大的标准差,代表大部分数值和其平均值之间差异较大;
一个较小的标准差,代表这些数值较接近平均值。
res = np.array([11,33,55,22,54])
np.std(res) # 17.378147196982766
方差ndarray.var()
衡量随机变量或一组数据时离散程度的度量
a= np.array([95,85,75, 65,55, 45])
b= np.array([73,72,71,69,68,67])
print( A组的方差为:’,a.var())
print('B组的方准差为:’,b.var())
求最大值、最小值、求和
# 最大值 max()
m1 = np.zeros(8*8,dtype='int').reshape((8,8))
print (m1)
print(m1 .max())
print('axis=0,从上往下査找:',m1.max(axis=0))
print('axis=1,从左往右査找:',m1.max(axis=1))
# 最小值 min()
print(m1)
print (ml.min())
print('axis=0,从上往下査找:’,m1.min(axis=0))
print('axis=1,从左往右査找:’,m1.min(axis=1))
# 求和 sum()
print (m1)
print(ml. sum())
print('axis=0,从上往下査找:’,ml.sum(axis=0))
print('axis=1,从左往右査找:’,m1.sum(axis=1))