小白的Numpy

Numpy基础

Numpy的简介

什么是Numpy

​NumPy(Numerical Python)是 Python 科学计算的基础包,它是一个开源的 Python 扩展库,用来支持大数据量的高维数组和矩阵运算,比 Python 自身的嵌套列表(该结构也可以用来表示矩阵)结构要高效的多。

​NumPy 提供了许多高级的数值编程工具,比如矩阵数据类型、矢量处理、高精度运算等,它专为严格的数字处理而产生。

NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:

  • 一个强大的 N 维数组对象 ndarray;
  • 广播功能函数;
  • 整合 C/C++/Fortran 代码的工具;
  • 线性代数、傅里叶变换、随机数生成等功能。

为什么使用Numpy

​由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。例如为了保存一个简单的[1,2,3],都需要有 3 个指针和 3 个整数对象。对于数值运算来说,这种结构显然比较浪费内存和 CPU 等宝贵资源。

​至于 array 对象,它可以直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,在上面的函数也不多,因此也不适合做数值运算。

Numpy 的诞生弥补了这些不足,它提供了两种基本的对象:ndarray(N-dimensional Array Object)和 ufunc(Universal Function Object)。ndarray 是存储单一数据类型的多维数组,而 ufunc 则是能够对数组进行处理的函数。

Numpy和机器学习

​在机器学习和深度学习中,图像、声音、文本等输入数据最终都要转换为数组或矩阵。如何有效地进行数组和矩阵的运算?这就需要充分利用Numpy。

如何使用Numpy

基础使用

基础操作

一般会将numpy更名为np来使用

import numpy as np
print(np.__version__)

数组大小

Z = np.zeros((10,10))
print(Z.size)		#100
ptint(Z.itemsize)	#8
创建数组

zeros() 函数创建一个全是零的数组,这是最基本和常用的创建n维数组的方法

Z = np.zeros(10)
print(Z) #[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

arange() 函数在想法上与range函数类似,也是创建数组的常用方法

Z = np.arange(10,30)
print(Z) #[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]

random() 方法课用于创建随机值数组

Z = np.random.random((3,3,3))
print(Z)
'''
[[[0.11757184 0.38776176 0.78979583]
  [0.13802877 0.48093353 0.61956751]
  [0.91376786 0.09106369 0.50310015]]

 [[0.03035367 0.89790108 0.87705693]
  [0.59908423 0.67145029 0.20128228]
  [0.46814959 0.39326309 0.79544883]]

 [[0.81819206 0.68706919 0.69438302]
  [0.59874449 0.66192036 0.74282909]
  [0.23223406 0.27830052 0.61605617]]]
'''

eye() 函数创建单位矩阵

Z = np.eye(3)
print(Z)
'''
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
 '''

使用 diag() 方法创建对角矩阵,并获得一个矩阵的对角元素

z=np.diag([1,2,3])
'''
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])
'''
np.diag(z) #array([1, 2, 3])

使用 tile() 方法创建,根据给定的参数和次数创建数组

其中第一个参数是想要重复的数组,第二个参数是对应维度的重复次数

a = np.array([0, 1, 2])
np.tile( a, [2, 2])
'''
array([[0, 1, 2, 0, 1, 2],
       [0, 1, 2, 0, 1, 2]])
'''

np.tile( a, 2)
'''
array([[0, 1, 2, 0, 1, 2]])
'''

c = np.array([1,2,3,4])
np.tile(c,(4,1))
'''
array([[1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4],
       [1, 2, 3, 4]])
'''

还可以使用fromiter方法,下面会提到

nan和inf

nan

首先,Numpy 中的nan为not a number,表示一个不确定的数

  • 两个nan是不相等的.

  • nan是浮点型的。

  • Numpy中有一个判断数组元素是否为nan是方法isnan(),返回一个bool类型的数组.

  • max, min, median等都是默认非nan安全的,需要加上nan来标记nan安全。

n = np.array([1,2,3,4,5]).astype("float")
n[2] = np.nan
print(n) #array([1., 2., nan, 4.,5.])
print(np.isnan(n)) #array([False, False, True,  Flase, False])

一下是对nan的一些操作

0 * np.nan				#nan
np.nan == np.nan		#False
np.nan - np.nan			#nan
np.nan in set([np.nan])	#True			

inf

numpy中的inf表示一个无限大的正数

np.inf>999999999999999  #True
np.inf > np.nan			#False
np.array([ 1, 2, 3])/0	#array([ inf,  inf, inf])

对已创建的数组的一些操作

对数组取逆

Z = np.arange(10)
Z = Z[::-1]
print(Z) #[9 8 7 6 5 4 3 2 1 0]

修改值数组中某位置的值

Z = np.zeros(10)
Z[4] = 1
print(Z) #[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]

修改数组的维度

Z = np.arange(9)
print(Z) #[0 1 2 3 4 5 6 7 8]
print(Z.reshape(3, 3))
'''
[[0 1 2]
 [3 4 5]
 [6 7 8]]
 '''
求数组中的特殊值

使用4种不同的方法提取正数随机数组的整数部分

Z = np.random.uniform(0,10,10)

print(Z - Z%1)
print(Z // 1)
print(np.floor(Z))
print(Z.astype(int))
print(np.trunc(Z))

求值:

Z = np.random.randint(0,10,size = [5,5])
'''
array([[1, 2, 6, 9, 0],
       [8, 5, 8, 1, 9],
       [0, 0, 6, 7, 8],
       [6, 0, 6, 9, 4],
       [6, 1, 3, 6, 1]])
'''

最大值 max

如果是查询元素的最大值,则参数为空

print(Z.max()) #9

查询列向量中最大值,需加上参数0或者axis=0

Ps:在numpy中,axis指的是向量的不同轴

print(Z.max(0)) #print(Z.max(axis=0))
#[8, 5, 8, 9, 9]

同理课查询行向量的最大值

print(Z.max(1)) #print(z.max(axis=1))
#[9 9 8 9 6]

最小值 min

与最大值一样

print(Z.min()) #0
print(Z.min(0)) #[0 0 3 1 0]
print(Z.min(1)) #[0 1 0 0 1]

平均值 mean

同理,可用mean()函数求矩阵的平均值

print(Z.mean()) #4.48
print(Z.mean(0)) #[4.2 1.6 5.8 6.4 4.4]
print(Z.mean(1)) #[3.6 6.2 4.2 5.  3.4]

numpy中也带了求最大最小平均值的函数

print(np.amax(Z,axis=0))
print(np.amin(Z,axis=0))
print(np.mean(Z,axis=0))

方差 Variance

​ 方差是在概率论和统计方差衡量随机变量或一组数据时离散程度的度量。概率论中方差用来度量随机变量和其数学期望(即均值)之间的偏离程度。统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。

在numpy中可使用var()函数来得到数组的方差

print(Z.var()) #10.249600000000001

标准偏差 standard deviation:

标准偏差=方差的开方,可用用sqrt()方法开方,也可以直接用std()方法得到

print(Z.std) #print(np.sqrt(Z.var))
#3.2014996486021987

中位数 median

print(np.median(Z)) #6.0

和 sum

print(Z.sum()) #print(np.sum(Z))
#112

找到数组中的非零元素的索引

nz = np.nonzero([1,2,0,0,4,0])
print(nz) #(array([0, 1, 4], dtype=int64),)

在(6,7,8)的数组中找到第100个元素的索引

print(np.unravel_index(99,(6,7,8))) #( 1, 5, 3)
对数组做变换

构建一个1在周围,0在内部的二维数组

Z = np.ones((10,10))
Z[1:-1,1:-1] = 0
print(Z)
'''
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
 '''

将数组中在大小在3-8中的元素改为对应的相反数

Z = np.arange(11)
Z[(3 < Z) & (Z < 8)] *= -1
#array([ 0,  1,  2,  3, -4, -5, -6, -7,  8,  9, 10])

在二维数组中随机放置p个元素

n = 5
p = 3
Z = np.zeros((n,n))
'''
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.]])
'''
np.put(Z, np.random.choice(range(n*n), p, replace=False),1)
print(Z)
'''
[[0. 0. 1. 0. 1.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0.]]
'''

排序一个数组的第n列

Z = np.random.randint(0,10,(3,3))
print(Z)
print(Z[Z[:,1].argsort()])

其它变换

对数组的变换就是对其中每个元素的变换

z = np.random.randint(1, 5, 5)
#array([1, 3, 3, 1, 3])

z**z		#array([ 1, 27, 27,  1, 27], dtype=int32)
Z <- Z		#array([False, False, False, False, False])
z/2			#array([0.5, 1.5, 1.5, 0.5, 1.5])

使数组变为只读状态

Z = np.zeros(10)
Z.flags.writeable = False
矩阵运算
a = np.arange(0, 15).reshape([5, 3])
b = np.arange(9, 3, -1).reshape([3, 2])
c = np.arange(2, 8).reshape([3, 2])
矩阵相乘
#使用dot()函数
np.dot(a, b)
#更简便的方法
a @ b
'''
array([[ 17,  14],
       [ 80,  68],
       [143, 122],
       [206, 176],
       [269, 230]])
'''

以下np.*(a,b,out=None)

矩阵相加、相减
#使用add()方法
np.add(c, b)
#或者直接用+
b + c
'''
array([[11, 11],
       [11, 11],
       [11, 11]])
'''

#使用subtract()方法
np.subtract(b, c)
#直接用-
b - c
'''
array([[ 7,  5],
       [ 3,  1],
       [-1, -3]])
'''
矩阵在对应位置处相乘、除
#使用multiply()方法
np.multiply(b, c)
#使用*
b * c
'''
array([[18, 24],
       [28, 30],
       [30, 28]])
'''

#使用divide()方法
np.divide(b, c)
#使用/
b / c
'''
array([[4.5       , 2.66666667],
       [1.75      , 1.2       ],
       [0.83333333, 0.57142857]])
'''
得到负矩阵

np.negative(a,out=None)

#使用negative()方法
np.negative(a,out=a)
#-a
-a
'''
array([[  0,  -1,  -2],
       [ -3,  -4,  -5],
       [ -6,  -7,  -8],
       [ -9, -10, -11],
       [-12, -13, -14]])
'''

常用函数

numpy.arange()

numpy.arange([start, ]stop, [step, ]dtype=None)

在给定的时间间隔内返回均匀间隔的值。值在半开的区间(start, stop)内生成(包括start但不包括stop的时间间隔)。对于整型参数,该函数相当于Python内建的range函数,但返回的是ndarray而不是list

用法与python中的range相似,作用也相同

z = np.arange(0,10)
#array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Z = np.arange('2020-11', '2020-12', dtype='datetime64[D]')
'''
array(['2020-11-01', '2020-11-02', '2020-11-03', '2020-11-04',
       '2020-11-05', '2020-11-06', '2020-11-07', '2020-11-08',
       '2020-11-09', '2020-11-10', '2020-11-11', '2020-11-12',
       '2020-11-13', '2020-11-14', '2020-11-15', '2020-11-16',
       '2020-11-17', '2020-11-18', '2020-11-19', '2020-11-20',
       '2020-11-21', '2020-11-22', '2020-11-23', '2020-11-24',
       '2020-11-25', '2020-11-26', '2020-11-27', '2020-11-28',
       '2020-11-29', '2020-11-30'], dtype='datetime64[D]')
'''
numpy.dtype()

numpy.dtype(obj, align=False, copy=False)

用来创建一个数据类型对象。

numpy.sum()

numpy.sum(a, axis=None, dtype=None, out=None, keepdims=, initial=, where=)

Numpy中重写了sum函数,第二个参数改为了axis,而原python中的第二个参数为start

print(sum(range(5),-1))#9
from numpy import *
print(sum(range(5),-1))#10
numpy.ceil()

按元素返回输入的上限。

a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
np.ceil(a)
'''
array([-1., -1., -0.,  1.,  2.,  2.,  2.])
'''
numpy.copysign()

numpy.copysign(x1, x2) 将把x1中元素的符号换成x2中元素的符号。

np.copysign(1.3, -1) 				#-1.3
np.copysign([1,2,3,4],[-1,1,1,-2]) 	#array([-1.,  2.,  3., -4.])
numpy.intersect1d()

找到两个数组的交点

Z1 = np.random.randint(0,10,10)
Z2 = np.random.randint(0,10,10)
print(np.intersect1d(Z1,Z2))
#[0 1 2 3 8 9]
np.datetime64()\np.timedelta64()
yesterday = np.datetime64('today') - np.timedelta64(1)
today     = np.datetime64('today')
tomorrow  = np.datetime64('today') + np.timedelta64(1)
np.trunc()

按元素返回输入的截断值。

Z = np.random.uniform(0,10,10)
print(np.trunc(Z))
numpy.matrix.astype()

复制数组,强制转换为指定类型。

x = np.array([1, 2, 2.5]) 	#array([1. ,  2. ,  2.5])
x.astype(int) 				#array([1, 2, 2])
numpy.fromiter()

numpy.fromiter(iterable, dtype, count=-1)

count为要从iterable中读取的项数。默认值是-1,这意味着读取所有数据。

def generate():
    for x in range(10):
        yield x
Z = np.fromiter(generate(),float)
numpy.linspace()

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)

在指定的时间间隔内返回均匀间隔的数字

#创建一个大小为10的向量,其值从0到1不等(不包括这两个值)
Z = np.linspace(0,1,11,endpoint=False)[1:]
'''
array([0.09090909, 0.18181818, 0.27272727, 0.36363636, 0.45454545,
       0.54545455, 0.63636364, 0.72727273, 0.81818182, 0.90909091])
'''
numpy.sort()\numpy.matrix.sort

numpy.sort()函数返回对数组排序的副本,而numpy.matrix.sort则是直接将数组进行排序

a=np.random.uniform(size=5)
#array([0.97735557, 0.33627009, 0.94749747, 0.05794612, 0.4470596 ])
np.sort(a)
#array([0.05794612, 0.33627009, 0.4470596 , 0.94749747, 0.97735557])
print(a)
#array([0.97735557, 0.33627009, 0.94749747, 0.05794612, 0.4470596 ])
a.sort()
#array([0.05794612, 0.33627009, 0.4470596 , 0.94749747, 0.97735557])
print(a)
#array([0.05794612, 0.33627009, 0.4470596 , 0.94749747, 0.97735557])
numpy.ufunc.reduce()

通过沿一个轴应用ufunc,将a的维数减少1。

Z = np.arange(10)
np.add.reduce(Z)
#速度比np.sum(Z)快
np.allclose()

如果两个数组的元素相等,则返回True(假设数组的形状相同,并且两个值的比较有一个容忍度)

容忍度意思为大概相等即可

A = np.random.randint(0,3,5)
B = np.random.randint(0,3,5)

equal = np.allclose(A,B)
print(equal)
np.array_equal()

如果两个数组具有相同的形状和元素,则为真,否则为假。

A = np.random.randint(0,3,5)
B = np.random.randint(0,3,5)

equal = np.array_equal(A,B)
print(equal)
numpy.argmax()

沿着一个轴返回最大值的索引。

Z = np.random.random(10)
'''
array([0.80224694, 0.01466865, 0.74560453, 0.15312313, 0.0860648 ,
       0.6472681 , 0.39663459, 0.1053029 , 0.35001286, 0.62869211])
'''
print(Z.argmax()) #0
numpy.meshgrid()

将坐标向量返回坐标矩阵,常与linspace共用。

可看看大佬的博客

>>> nx, ny = (3, 2)
>>> x = np.linspace(0, 1, nx)
>>> y = np.linspace(0, 1, ny)
>>> xv, yv = np.meshgrid(x, y)
>>> xv
array([[0. , 0.5, 1. ],
       [0. , 0.5, 1. ]])
>>> yv
array([[0.,  0.,  0.],
       [1.,  1.,  1.]])
matrix.view([dtype][, type])

使用相同数据的数组的新视图。

Z = (np.random.rand(10)*100).astype(np.float32)
print(Z.view(np.int32))
numpy.ndindex(*shape)

指向索引数组的n维迭代器对象。

>>> for index in np.ndindex(3, 2, 1):
...     print(index)
(0, 0, 0)
(0, 1, 0)
(1, 0, 0)
(1, 1, 0)
(2, 0, 0)
(2, 1, 0)

常用类

Linear algebra (numpy.linalg)

Numpy线性代数函数依赖于BLAS和LAPACK来提供标准线性代数算法的高效低层实现,NumPy本身可以使用其参考实现子集的C版本提供这些库。但是如果可以,优先考虑利用专用处理器功能的高度优化的库。这类库的例子有OpenBLAS、MKL ™和ATLAS。因为这些库是多线程和处理器相关的,可能需要环境变量和外部包(比如threadpoolctl)来控制线程数量或指定处理器体系结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值