numpy快速入门(一)
numpy快速入门(一)
原文链接
NUMPY简介
NumPy是使用Python进行科学计算的基础包。它包含如下内容:
- 一个强大的N维数组对象
- 复杂的(广播)功能
- 用于集成C / C ++和Fortran代码的工具
- 有用的线性代数,傅里叶变换和随机数功能
除了明显的科学用途外,NumPy还可以用作通用数据的高效多维容器。可以定义任意数据类型。这使NumPy能够无缝快速地与各种数据库集成。
安装方式
安装方式有很多种,比如通过源码安装,通过wheel文件安装等,其实最方便最常用的还是通过pip安装:
pip install numpy
新手入门
入门条件
在阅读本教程之前,您应该了解一些Python。如果您想重温记忆,请查看Python教程。
如果您希望使用本教程中的示例,则还必须在计算机上安装某些软件。有关说明,请参阅 http://scipy.org/install.html。
基础知识
NumPy的主要对象是同构多维数组。它是一个元素表(通常是数字),都是相同的类型,由正整数元组索引。在NumPy维度中称为轴。
例如,3D空间中的点的坐标[1, 2, 1]具有一个轴。该轴有3个元素,所以我们说它的长度为3.在下面所示的例子中,数组有2个轴。第一轴的长度为2,第二轴的长度为3。
import numpy as np
a=np.array([
[1,2,3],
[4,5,6]
])
print('第一个轴的长度是:{}'.format(len(a)))
print('第二个轴的长度是:{}'.format(len(a[0])))
第一个轴的长度是:2
第二个轴的长度是:3
numpy的数组类是ndarray,它的别名是array。请注意,numpy.array这与标准Python库类array.array不同,后者仅处理一维数组并提供较少的功能。ndarray对象更重要的属性是:
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
该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。
下面举了两个例子,注意对比理解属性的变化
import numpy as np
a=np.array([
[1,2,3],
[4,5,6]
])
print('ndarray.ndim:',a.ndim)
print('ndarray.shape:',a.shape)
print('ndarray.size:',a.size)
print('ndarray.dtype:',a.dtype)
print('ndarray.itemsize:',a.itemsize)
ndarray.ndim: 2
ndarray.shape: (2, 3)
ndarray.size: 6
ndarray.dtype: int32
ndarray.itemsize: 4
import numpy as np
a=np.arange(32).reshape(4,4,2)
print(a)
print('ndarray.ndim:',a.ndim)
print('ndarray.shape:',a.shape)
print('ndarray.size:',a.size)
print('ndarray.dtype:',a.dtype)
print('ndarray.itemsize:',a.itemsize)
[[[ 0 1]
[ 2 3]
[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]
[12 13]
[14 15]]
[[16 17]
[18 19]
[20 21]
[22 23]]
[[24 25]
[26 27]
[28 29]
[30 31]]]
ndarray.ndim: 3
ndarray.shape: (4, 4, 2)
ndarray.size: 32
ndarray.dtype: int32
ndarray.itemsize: 4
数组的创建
有几种创建数组的方法。例如,你可以使用array函数从常规Python列表或元组中创建数组。得到的数组的类型是从Python列表中元素的类型推导出来的。
从python数据中创建
import numpy as np
a=np.array([1,2,3,4,5])
print('a is :',a)
print('a\'s type is :',type(a))
print('a\'s dtype is :',a.dtype)
a is : [1 2 3 4 5]
a's type is : <class 'numpy.ndarray'>
a's dtype is : int32
一个常见的错误在于使用多个数值参数调用 array 函数,而不是提供一个数字列表(List)作为参数。
a = np.array(1,2,3,4) # WRONG
a = np.array([1,2,3,4]) # RIGHT
用numpy生成占位符
通常,数组的元素最初是未知的,但它的大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组。这就减少了数组增长的必要,因为数组增长的操作花费很大。
函数 zeros 创建一个由0组成的数组,函数 ones 创建一个由1数组的数组,函数 empty 内容是随机的并且取决于存储器的状态。默认情况下,创建的数组的dtype是 float64。
import numpy as np
a=np.zeros((4,2))
b=np.ones((4,2))
c=np.empty((4,2))
print('result of np.zeros((4,2)) is :\n',a,'\n')
print('result of np.ones((4,2)) is :\n',b,'\n')
print('result of np.empty((4,2)) is :\n',c,'\n')
result of np.zeros((4,2)) is :
[[0. 0.]
[0. 0.]
[0. 0.]
[0. 0.]]
result of np.ones((4,2)) is :
[[1. 1.]
[1. 1.]
[1. 1.]
[1. 1.]]
result of np.empty((4,2)) is :
[[0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000]
[0.00000000e+000 6.18570189e-321]
[3.11510340e-307 3.11521375e-307]]
使用arange函数创建
要创建数字序列,NumPy提供了一个类似于 range 的函数,该函数返回数组而不是列表。
import numpy as np
a=np.arange(10,30,5)#10代表起始数,30代表终止数,5代表步长
print('a is :',a)
print('a\'s type is :',type(a))
print('a\'s dtype is :',a.dtype)
a is : [10 15 20 25]
a's type is : <class 'numpy.ndarray'>
a's dtype is : int32
当 arange 与浮点参数一起使用时,由于浮点数的精度是有限的,通常不可能预测获得的元素数量。出于这个原因,通常最好使用函数 linspace ,它接收我们想要的元素数量而不是步长作为参数:
from numpy import pi
a=np.linspace(0,2,9)#从0到2之间取9个数
b=np.linspace( 0, 2*pi, 10 )# 在取值数量很多时适用
c=np.sin(b)
print('a is :\n',a,'\n')
print('a\'s type is :',type(a),'\n')
print('a\'s dtype is :',a.dtype,'\n')
print('b is :\n',b,'\n')
print('b\'s type is :',type(b),'\n')
print('b\'s dtype is :',b.dtype,'\n')
print('c is :\n',c,'\n')
print('c\'s type is :',type(c),'\n')
print('c\'s dtype is :',c.dtype,'\n')
a is :
[0. 0.25 0.5 0.75 1. 1.25 1.5 1.75 2. ]
a's type is : <class 'numpy.ndarray'>
a's dtype is : float64
b is :
[0. 0.6981317 1.3962634 2.0943951 2.7925268 3.4906585
4.1887902 4.88692191 5.58505361 6.28318531]
b's type is : <class 'numpy.ndarray'>
b's dtype is : float64
c is :
[ 0.00000000e+00 6.42787610e-01 9.84807753e-01 8.66025404e-01
3.42020143e-01 -3.42020143e-01 -8.66025404e-01 -9.84807753e-01
-6.42787610e-01 -2.44929360e-16]
c's type is : <class 'numpy.ndarray'>
c's dtype is : float64
另见:
array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, numpy.random.rand, numpy.random.randn, fromfunction, fromfile
打印数组
当你打印数组时,NumPy以与嵌套列表类似的方式显示它,但是具有以下布局:
- 最后一个轴从左到右打印,
- 倒数第二个从上到下打印,
- 其余的也从上到下打印,每个切片与下一个用空行分开。
一维数组被打印为行、二维为矩阵和三维为矩阵列表。
a = np.arange(6)
print('一维打印')
print(a)#一维打印
b = np.arange(12).reshape(4,3)
print('二维打印')
print(b)#二维打印
c = np.arange(24).reshape(2,3,4)
print('三维打印')
print(c)#三维打印
一维打印
[0 1 2 3 4 5]
二维打印
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
三维打印
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
#如果数组太大而无法打印,NumPy将自动跳过数组的中心部分并仅打印角点:
print(np.arange(10000))
print(np.arange(10000).reshape(100,100))
[ 0 1 2 ... 9997 9998 9999]
[[ 0 1 2 ... 97 98 99]
[ 100 101 102 ... 197 198 199]
[ 200 201 202 ... 297 298 299]
...
[9700 9701 9702 ... 9797 9798 9799]
[9800 9801 9802 ... 9897 9898 9899]
[9900 9901 9902 ... 9997 9998 9999]]
#要禁用此行为并强制NumPy打印整个数组,你可以使用 set_printoptions 更改打印选项。
np.set_printoptions(threshold=np.nan)
基本操作
在数组元素上进行数学运算,产生新的数组。
import numpy as np
a=np.array([1,2,3,4])
b=np.arange(4)
c=a-b
d=a**2
e=10*np.sin(a)
f=a<3
print('a is:\n',a,'\n')
print('b is:\n',b,'\n')
print('c(a-b) is:\n',c,'\n')
print('d(a**2) is:\n',d,'\n')
print('e(10*np.sin(a)) is:\n',e,'\n')
print('c(a<3) is:\n',f,'\n')
a is:
[1 2 3 4]
b is:
[0 1 2 3]
c(a-b) is:
[1 1 1 1]
d(a**2) is:
[ 1 4 9 16]
e(10*np.sin(a)) is:
[ 8.41470985 9.09297427 1.41120008 -7.56802495]
c(a<3) is:
[ True True False False]
与许多矩阵语言不同,乘法运算符 * 的运算在NumPy数组中是元素级别的,也称为哈达马积。矩阵乘积可以使用@运算符(在python> = 3.5中)或dot函数或方法执行:
a=np.array( [[1,1],[0,1]])
b=np.array( [[2,0],[3,4]])
c=a*b#元素乘积
d=a@b#矩阵乘积
e=a.dot(b)#另一种矩阵乘积的方式
print('a is:\n',a,'\n')
print('b is:\n',b,'\n')
print('c(a*b) is:\n',c,'\n')
print('d(a@b) is:\n',d,'\n')
print('e(a.dot(b)) is:\n',e,'\n')
a is:
[[1 1]
[0 1]]
b is:
[[2 0]
[3 4]]
c(a*b) is:
[[2 0]
[0 4]]
d(a@b) is:
[[5 4]
[3 4]]
e(a.dot(b)) is:
[[5 4]
[3 4]]
某些操作(例如+=和*=)适用于修改现有数组,而不是创建新数组。
a = np.ones((2,3), dtype=int)
print('a is :\n',a,'\n')
a *= 3
print('a *= 3 is :\n',a,'\n')
b = np.random.random((2,3))
print('b is :\n',b,'\n')
b +=a
print('b +=a is :\n',b,'\n')
a += b # b不会自动转换成int类型,会报错
a is :
[[1 1 1]
[1 1 1]]
a *= 3 is :
[[3 3 3]
[3 3 3]]
b is :
[[0.49859704 0.93300205 0.03490493]
[0.04724951 0.45715042 0.38407476]]
b +=a is :
[[3.49859704 3.93300205 3.03490493]
[3.04724951 3.45715042 3.38407476]]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-26-b1ab720e80e5> in <module>
8 print('b +=a is :\n',b,'\n')
9
---> 10 a += b # b不会自动转换成int类型,会报错
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
当使用不同类型的数组操作时,结果数组的类型对应于更一般或更精确的数组(称为向上转换的行为)。
a = np.ones(3, dtype=np.int32)
b = np.linspace(0,pi,3)
c = a+b
d = np.exp(c*1j)
print('a.dtype.name is ',a.dtype.name)
print('b.dtype.name is ',b.dtype.name)
print('c.dtype.name is ',c.dtype.name)
print('d.dtype.name is ',d.dtype.name)
a.dtype.name is int32
b.dtype.name is float64
c.dtype.name is float64
d.dtype.name is complex128
许多一元运算,例如计算数组中所有元素的总和,都是作为 ndarray 类的方法实现的。
a = np.random.random((2,3))
sum=a.sum()
min=a.min()
max=a.max()
print('a is:\n ',a,'\n')
print('sum(a.sum()) is:\n',sum,'\n')
print('min(a.min()) is:\n',min,'\n')
print('max(a.max()) is:\n',max,'\n')
a is:
[[0.50477827 0.7117427 0.02840961]
[0.96608057 0.02399329 0.67794353]]
sum(a.sum()) is:
2.9129479747742897
min(a.min()) is:
0.02399329487095969
max(a.max()) is:
0.9660805718319886
默认情况下,这些操作适用于数组,就好像它是数字列表一样,无论其形状如何。但是,通过指定 axis 参数,你可以沿着数组的指定轴应用操作:
a = np.arange(12).reshape(3,4)
sum=a.sum(axis=0)# sum of each column
min=a.min(axis=1) # min of each row
cumsum=a.cumsum(axis=1)# cumulative sum along each row
print('a is:\n ',a,'\n')
print('sum(a.sum()) is:\n',sum,'\n')
print('min(a.min()) is:\n',min,'\n')
print('cumsum(a.cumsum()) is:\n',cumsum,'\n')
a is:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
sum(a.sum()) is:
[12 15 18 21]
min(a.min()) is:
[0 4 8]
cumsum(a.cumsum()) is:
[[ 0 1 3 6]
[ 4 9 15 22]
[ 8 17 27 38]]
通用函数
NumPy提供熟悉的数学函数,例如sin,cos和exp。在NumPy中,这些被称为“通用函数”(ufunc)。在NumPy中,这些函数在数组上以元素方式运行,产生一个数组作为输出。
a=np.arange(3)
b=np.exp(a)
c=np.sqrt(a)
print('a is:\n ',a,'\n')
print('b is:\n ',b,'\n')
print('c is:\n ',c,'\n')
a is:
[0 1 2]
b is:
[1. 2.71828183 7.3890561 ]
c is:
[0. 1. 1.41421356]
另请参见:
all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot, vectorize, where
索引、切片和迭代
一维数组可以被索引,切片和迭代,就像列出和其他Python序列一样。
a = np.arange(10)**3
print('a is:\n ',a,'\n')
print('a[2] is:',a[2],'\n')
print('a[2:5] is:',a[2:5],'\n')
a[:6:2] = -1000# equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
print('a is:\n ',a,'\n')
print('a[ : :-1] is:\n ',a[ : :-1],'\n')#倒排a
for i in a:
print(i**(1/3.))#由于jupyter的原因,这里报错了
a is:
[ 0 1 8 27 64 125 216 343 512 729]
a[2] is: 8
a[2:5] is: [ 8 27 64]
a is:
[-1000 1 -1000 27 -1000 125 216 343 512 729]
a[ : :-1] is:
[ 729 512 343 216 125 -1000 27 -1000 1 -1000]
nan
1.0
nan
3.0
nan
5.0
5.999999999999999
6.999999999999999
7.999999999999999
8.999999999999998
d:\testproj\test_python\zhyblog\venv\lib\site-packages\ipykernel_launcher.py:9: RuntimeWarning: invalid value encountered in power
if __name__ == '__main__':
多维(Multidimensional) 数组每个轴可以有一个索引。 这些索在元组中以逗号分隔给出:
def f(x,y):
return 10*x+y
a = np.fromfunction(f,(5,4),dtype=int)
print('a is:\n ',a,'\n')
print('a[2,3] is ',a[2,3])
print('a[0:5,1] is ',a[0:5,1])# each row in the second column of a
print('a[ : ,1] is ',a[ : ,1]) # equivalent to the previous example
print('a[1:3, : ] is \n',a[1:3, : ])# each column in the second and third row of b
a is:
[[ 0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]]
a[2,3] is 23
a[0:5,1] is [ 1 11 21 31 41]
a[ : ,1] is [ 1 11 21 31 41]
a[1:3, : ] is
[[10 11 12 13]
[20 21 22 23]]
当提供比轴数更少的索引时,缺失的索引被认为是一个完整切片 :
a[-1]
array([40, 41, 42, 43])
b[i] 方括号中的表达式 i 被视为后面紧跟着 : 的多个实例,用于表示剩余轴。NumPy也允许你使用三个点写为 b[i,...]。
三个点( ... )表示产生完整索引元组所需的冒号。例如,如果 x 是rank为的5数组(即,它具有5个轴),则
- x[1,2,...] 等于 x[1,2,:,:,:]
- x[...,3] 等效于 x[:,:,:,:,3]
- x[4,...,5,:] 等效于 x[4,:,:,5,:]
c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
[ 10, 12, 13]],
[[100,101,102],
[110,112,113]]])
print('c.shape is ',c.shape,'\n')
print('c[1,...] is :\n',c[1,...],'\n') # same as c[1,:,:] or c[1]
print('c[...,2] is :\n',c[...,2],'\n') # same as c[:,:,2]
c.shape is (2, 2, 3)
c[1,...] is :
[[100 101 102]
[110 112 113]]
c[...,2] is :
[[ 2 13]
[102 113]]
迭代(Iterating) 多维数组是相对于第一个轴完成的:
for row in c:
print(row,'\n')
[[ 0 1 2]
[10 12 13]]
[[100 101 102]
[110 112 113]]
但是,如果想要对数组中的每个元素执行操作,可以使用 flat 属性,该属性是数组中所有元素的迭代器:
for element in c.flat:
print(element)
0
1
2
10
12
13
100
101
102
110
112
113
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律