In [227]:
import numpy as np
In [ ]:
# NumPy是Python中科学计算的基础软件包。
# 它是一个提供多了维数组对象,多种派生对象(如:掩码数组、矩阵)以及用于快速操作数组的函数及API,
# 它包括数学、逻辑、数组形状变换、排序、选择、I/O 、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等等。# NumPy包的核心是ndarray对象。# 它封装了python原生的同数据类型的n维数组,为了保证其性能优良,其中有许多操作都是代码在本地进行编译后执行的。# NumPy数组 和 标准Python Array(数组) 之间 的区别# NumPy数组在创建时具有固定的大小,与Python的原生数组对象(可以动态增长)不同。 更改ndarray的大小将创建一个新数组并删除原来的数组。# NumPy数组中的元素都需要具有相同的数据类型,因此在内存中的大小相同。 例外情况:Python的原生数组里包含了NumPy的对象的时候,# 这种情况下就允许不同大小元素的数组。
# 安装# python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
In [2]:
# NumPy的主要对象是同类型的多维数组。它是一张表,所有元素(通常是数字)的类型都相同,并通过正整数元组索引。在NumPy中,维度称为轴。
# 轴的数目为rank。
# [1, 2, 1] 是rank为1的数组,因为它具有一个轴。该轴的长度为3
t1 = [[ 1., 0., 0.],
[ 0., 1., 2.]]
# t1 有两个轴 第一个轴(维度)的长度为2,第二个轴(维度)的长度为3。
In [3]:
# 主要属性# ndarray.ndim:数组的轴(维度)的个数。在Python世界中,维度的数量被称为rank。
# ndarray.shape:数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于有n行和m列的矩阵,shape将是(n,m)。因此,
# shape元组的长度就是rank或维度的个数 ndim。
# ndarray.size:数组元素的总数。这等于shape的元素的乘积。
# ndarray.dtype:一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。
# 例如numpy.int32、numpy.int16和numpy.float64。
# ndarray.itemsize:数组中每个元素的字节大小。例如,元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的
# itemsize 为4(=32/8)。它等于 ndarray.dtype.itemsize 。
# ndarray.data:该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。
In [50]:
# 创建数组
In [228]:
# 1. 用普通的python列表创建数组
a1 = np.array([1,2,3])
print(a1.ndim)
print(a1.dtype)
print(a1.size)
print(a1.shape)
a1
Out[228]:
In [9]:
a2 = a1 = np.array([[1,2,3], [3,4,5]], dtype='int')
a2
Out[9]:
In [12]:
print(a2.ndim)
print(a2.dtype)
print(a2.size)
print(a2.shape)
In [ ]:
# 用 nunpy 内置的方法来创建数组
In [18]:
#np.zeros(shape, dtype=None, order='C')
#创建shape是3x5的全1(默认浮点型)数组
a3= np.zeros((3,5), order='C')
a3
Out[18]:
In [17]:
#np.zeros(shape, dtype=None, order='C')
#创建shape是3x5的全1(默认浮点型)数组
a4 = np.ones((3,5))
a4
Out[17]:
In [19]:
#np.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')
#创建一个形状为 N x N 的单位矩阵(二维数组)
a5 = np.eye(3)
a5
Out[19]:
In [21]:
#empty(shape, dtype=float, order='C')
#创建一个形状为shape的未初始化数组,值为随机值
a6 =np.empty(5, dtype='int')
Out[21]:
In [23]:
a7 = np.empty((3,4))
a7
Out[23]:
In [34]:
#np.full(shape, fill_value, dtype=None, order='C')
#创建shape是3x5的(默认浮点型)数组,值fill_value都是3.14
a7 = np.full((3,5),5)
a7
Out[34]:
In [35]:
# 使用 arange 来创建
# arange([start,] stop[, step,], dtype=None)
a8 = np.arange(0,20,5)
a8
Out[35]:
In [230]:
# 使用linspace 来创建
# np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
a9= np.linspace(10,20,6)
a9
Out[230]:
In [233]:
# reshape
a10 = a9.reshape(2,3)
a10
Out[233]:
In [51]:
# 形状 和操作
In [236]:
aa = np.arange(20).reshape(4,5)
aa
Out[236]:
In [237]:
print(aa.shape)
print(aa.size)
In [43]:
aa.reshape(5,4) # 不改变数组本身
Out[43]:
In [44]:
aa
Out[44]:
In [45]:
aa.ravel() # 不改变数组本身
Out[45]:
In [46]:
aa
Out[46]:
In [238]:
aa
Out[238]:
In [239]:
aa.resize(5,4) # 改变数组本身
In [240]:
aa
Out[240]:
In [241]:
aa.reshape(5,-1) #reshape操作中将维度指定为-1,则会自动计算其他维度
Out[241]:
In [52]:
# 将不同的数组堆叠在一起
In [243]:
aa = np.floor(10*np.random.random((2,2)))
aa
Out[243]:
In [244]:
bb = np.floor(10*np.random.random((2,2)))
bb
Out[244]:
In [245]:
xx = np.vstack((aa,bb))
xx
Out[245]:
In [246]:
np.hstack((aa, bb))
Out[246]:
In [60]:
# numpy 切片和索引
In [61]:
a = np.arange(10)
a
Out[61]:
In [67]:
s = slice(2,7,2)
print(a[s])
In [68]:
b = a[2:7:2]
b
Out[68]:
In [250]:
aa = np.floor(10*np.random.random((2,12)))
aa
Out[250]:
In [258]:
aa
Out[258]:
In [259]:
np.hsplit(aa,3) # 平均分成3份
Out[259]:
In [260]:
np.hsplit(aa,(3,4)) # 0-3 3-4 4-
Out[260]:
In [73]:
# 分割
aa = np.random.randint(1, 50,size=(7,7))
aa
Out[73]:
In [74]:
# np.split(arr,index,axis)
# arr 为被切分的数组
# index(整数或者数组) # 如果是一个整数 就把当前数组平均分成index份,如果数组的size不能被index整除则报错,# 如果为一个数组,则沿的数组的轴线进行切分,比如:[2, 3] 则会被切割成[:2],[2:3],[3:]
# axis 为切分的方向 默认为0 横向 1为竖向np.split(aa, [2,4,6], axis=1)
Out[74]:
In [75]:
aa
Out[75]:
In [76]:
aa[5]
Out[76]:
In [77]:
aa[5,3]
Out[77]:
In [78]:
aa[5:]
Out[78]:
In [79]:
aa[:,1:2]
Out[79]:
In [261]:
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
print("-----------------")
print (a[...,1]) # 第2列元素
print("-----------------")
print (a[1,...]) # 第2行元素
print("-----------------")
print (a[...,1:]) # 第2列及剩下的所有元素# 三个点( ... )表示产生完整索引元组所需的冒号。例如,如果 x 是rank为的5数组(即,它具有5个轴),则# x[1,2,...] 等于 x[1,2,:,:,:]。
# x[...,3] 等效于 x[:,:,:,:,3]。
In [263]:
# 整数数组索引
# 实例获取数组中(0,0),(1,1)和(2,0)位置处的元素。
x = np.array([[1, 2], [3, 4], [5, 6]])
print(x)
print('--------------')
y = x[[0,1,2], [0,1,0]]
print (y)
In [85]:
#获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('我们的数组是:' )
print (x)
print ('\n')
rows = np.array([[0,0],[3,3]])
cols = np.array([[0,2],[0,2]])
y = x[rows,cols]
print ('这个数组的四个角元素是:')
print (y)
In [264]:
# 布尔索引
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print ('我们的数组是:')
print (x)
print ('\n')
# 现在我们会打印出大于 5 的元素
print ('大于 5 的元素是:')
print(x>5)
print (x[x > 5])
In [86]:
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])
In [92]:
np.nan == np.nan
Out[92]:
In [93]:
# 花式索引
# 花式索引指的是利用整数数组进行索引。# 花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,
# 那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。# 花式索引跟切片不一样,它总是将数据复制到新数组中。# 1、传入顺序索引数组
In [265]:
x=np.arange(32).reshape((8,4))
print(x)
print('--------------------')
print (x[[4,2,1,7]])
In [266]:
x=np.arange(32).reshape((8,4))
print (x[[-4,-2,-1,-7]])
In [268]:
print (x[([1,5,7,2],[0,3,1,2])])
In [270]:
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
In [226]:
x = np.array([[1,2],[3,4],[5,6]])
print(x)
print('-----------')
print(x[[0,1]])
print('-------------')
print(x[[0,1],[0,1]])
print('------------------')
# 使用numpy.ix_()函数增强可读性
print (x[np.ix_([0,1],[0,1])])
print('--------------')
x[[0,1],[0,1]] = [0,0]
print(x) # [[0,2],[3,0],[5,6]]
In [271]:
# 迭代数组
In [273]:
# 迭代
a = np.arange(6).reshape(2,3)
print ('原始数组是:')
print (a)
print ('\n')
print ('迭代输出元素:')
for x in np.nditer(a):print (x, end=", " )
print ('\n')
In [275]:
# for x in np.nditer(a, order='F'):Fortran order,即是列序优先;
# for x in np.nditer(a.T, order='C'):C order,即是行序优先;
a = np.arange(6).reshape(2,3)
print(a)
print('------------')
print(a.T)
for x in np.nditer(a, order ='C'):print (x, end=", " )
print ('\n')
In [117]:
for i in a:print(i)
In [123]:
# 修改数组中元素的值
# nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,
# 实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x
print ('修改后的数组是:')
print (a)
In [124]:
# numpy.ndarray.flat 是一个数组元素迭代器,实例如下:
a = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:print (row)#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:print (element)
In [125]:
# 数组操作
# numpy.ndarray.flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:
# ndarray.flatten(order='C')
# order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
a = np.arange(8).reshape(2,4)print ('原数组:')
print (a)
print ('\n')
# 默认按行print ('展开的数组:')
print (a.flatten())
print ('\n')print ('以 F 风格顺序展开的数组:')
print (a.flatten(order = 'F'))
In [127]:
# 翻转数组
In [276]:
# numpy.transpose 函数用于对换数组的维度 numpy.ndarray.T 类似 numpy.transposea = np.arange(12).reshape(3,4)print ('原数组:')
print (a )
print ('\n')print ('对换数组:')
print (np.transpose(a))
print('-------------------')
print(a.T)
In [134]:
# 轴的理解
In [277]:
a = np.array([[78, 34, 87, 25, 83], [25, 67, 97, 22, 13], [78, 43, 87, 45, 89]])
print(a)
print('-------------------')
print(a.max(axis=0))
print(a.max(axis=1))
#axis=0就是竖轴的数据 axis=1就是横轴的
In [278]:
a = np.array([[[0, 1], [2, 3]], [[4, 5], [6, 7]]])
print(a.shape)
print(a)
print('--------------')
print(a.max(axis=0))
print('-----------')
print(a.max(axis=1))
print('-------------')
print(a.max(axis=2))# 这里的最大值就是把一个一维数组当成了一个元素
In [279]:
# numpy.rollaxis 函数向后滚动特定的轴到一个特定位置
# numpy.rollaxis(arr, axis, start)
# arr:数组
# axis:要向后滚动的轴,其它轴的相对位置不会改变
# start:默认为零,表示完整的滚动。会滚动到特定位置。
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)print ('原数组:')
print (a)
print ('\n')
# 将轴 2 滚动到轴 0(宽度到深度)
# 程序运行np.rollaxis(a, 2)时,讲轴2滚动到了轴0前面,其他轴相对2轴位置不变(start默认0),数组下标排序由0,1,2变成了1,2,0print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2))
# 将轴 0 滚动到轴 1:(宽度到高度)
print ('\n')print ('调用 rollaxis 函数:')
print (np.rollaxis(a,2,1))
In [136]:
# numpy.swapaxes 函数用于交换数组的两个轴 numpy.swapaxes(arr, axis1, axis2)
# arr:输入的数组
# axis1:对应第一个轴的整数
# axis2:对应第二个轴的整数
# 创建了三维的 ndarray
a = np.arange(8).reshape(2,2,2)print ('原数组:')
print (a)
print ('\n')
# 现在交换轴 0(深度方向)到轴 2(宽度方向)print ('调用 swapaxes 函数后的数组:')
print (np.swapaxes(a, 2, 0))
In [137]:
# 随机数组
In [280]:
# 随机创建 指定形状的数组 0-1之间的数
np.random.rand(5)
Out[280]:
In [281]:
np.random.rand(5,5, 5)
Out[281]:
In [282]:
# 随机获取指定范围的一个数
np.random.uniform(0,100)
Out[282]:
In [283]:
# 随机获取指定范围的一个整数
np.random.randint(0,52)
Out[283]:
In [284]:
np.random.randint(0,20,size=(3,4))
Out[284]:
In [144]:
np.random.randint(0,20,size=(5,4))
Out[144]:
In [145]:
# np.random.choice(F,N,P)
# 从0-F范围里面去N个数(不包含N),P表示概率
np.random.choice(2,2)
Out[145]:
In [288]:
a1 = np.random.choice(5,3,p=[0.2,0,0.5,0.3,0])
a1
Out[288]:
In [150]:
b = np.random.randint(0,20,size=(5,4))
print(b)
In [151]:
np.random.shuffle(b)
print(b)
In [152]:
# 计算
In [153]:
a = [1,2,3,4]
b= np.array(a,dtype='float')
b
Out[153]:
In [154]:
b+1
Out[154]:
In [155]:
b
Out[155]:
In [156]:
a = np.array([1,3,5,7])
a
Out[156]:
In [157]:
# 同纬度且个数相同的数组相加
a+b
Out[157]:
In [289]:
# 数组a中大于3的数就会显示True小于3的数就会显示False
a[a>3]
Out[289]:
In [159]:
print(a)
a[a>3]
Out[159]:
In [161]:
c = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
c
Out[161]:
In [290]:
# 求出c中大于5且为偶数的元素
c[(c>5) & (c%2==0)]
Out[290]:
In [292]:
d=np.array([1.1,2.2,3.3,4.4,5.5,6.6,7.7])
d
Out[292]:
In [294]:
# 向上取整
print(np.ceil(d))
# 向下取整
print(np.floor(d))
# 绝对值
print(np.abs(d))
# 开方
print(np.sqrt(b))
# 分别去除小数部分和整数部分
print('------------------')
print(np.modf(d))
# e为底的指数函数
print(np.exp(d))
print(np.log(d))
# 四舍五入
print(np.round(d))
print('------------------')
print(np.rint(d))
# 向0取整
print(np.trunc(d))
# 是否不等于任何整数
print(np.isnan(d))
#
print(np.cos(b))
print(np.sin(b))
print(np.tan(b))# 上述操作 对普通列表 也实用
In [295]:
print(d)
print('-------------------------')
# 求和
print(d.sum())
# 平均值
print(d.mean())
# 等差数列
print(d.cumsum())
# 标准差
print(d.std())
# 方差
print(d.var())
# 最小值
print(d.min())
#最大值
print(d.max())
print('---------------')
# 最大值索引
print(d.argmin())
# 最小值索引
print(d.argmax())
In [297]:
a = np.array( [20,30,40,50] )
b = np.arange( 4 )
print(a)
print('-----')
print(b)
In [298]:
c = a-b
c
Out[298]:
In [174]:
b**2
Out[174]:
In [175]:
10*np.sin(a)
Out[175]:
In [307]:
# 与许多矩阵语言不同,乘法运算符 * 的运算在NumPy数组中是元素级别的。矩阵乘积可以使用 dot 函数或方法执行
a = np.array( [[1,1,1],[0,1,1]] )
a
Out[307]:
In [317]:
b = np.array( [[2,0], [3,4], [1,1] ])
b
Out[317]:
In [315]:
a*b
Out[315]:
In [318]:
a.dot(b)
Out[318]:
In [319]:
a = np.ones((2,3), dtype=int)
a
Out[319]:
In [320]:
a*=3
a
Out[320]:
In [322]:
b = np.random.randint(0,6, size=(2,3))
b
Out[322]:
In [323]:
b+=a
b
Out[323]:
In [325]:
print(a)
print(b)
a+=b
a
Out[325]:
In [ ]:
# 复制和视图
In [ ]:
# NumPy中,数组的复制有三种方式:
# Python通用的地址复制:通过 b = a 复制 a 的值,b 与 a 指向同一地址,改变 b 同时也改变 a。
# 通过视图ndarray.view()仅复制值,当对 c 值进行改变会改变 a 的对应的值,而改变 c 的 shape 不改变 a 的 shape。# ndarray.copy() 进行的完整的拷贝,产生一份完全相同的独立的复制。
In [210]:
a = np.arange(12)
a
Out[210]:
In [211]:
b=a
a is b
Out[211]:
In [212]:
c = a.view()c
Out[212]:
In [326]:
a is c
Out[326]:
In [216]:
c.shape = 2,6
c
Out[216]:
In [217]:
c [0,0] = 55
a
Out[217]:
In [218]:
d = a.copy()
d is a
Out[218]:
In [219]:
d
Out[219]:
In [221]:
d.shape = 2,6
d
Out[221]:
In [222]:
d[1,1] = 22
a
Out[222]:
In [ ]:
In [ ]: