【科学计算和数据分析】numpy 第一篇——快速入门

本专栏第一篇开始讲解NumPy数组,在这么多第三方库中,NumPy是属于比较繁杂但实用的一个库。本篇讲解NumPy基础入门,下一篇讲解numpy API。官方文档的内容比较多,不是非常适用的就不拿出来讲了,偶尔有兴趣可以再去通读官方文档。
官方文档:https://numpy.org/devdocs/user/quickstart.html

先放一下本篇所讲内容的思维导图,看懂教程再看思维导图理解,基本就能掌握NumPy库的一般用法了。
【科学计算和数据分析】numpy 第一篇——快速入门_第1张图片


NumPy快速入门

  • 1.NumPy是什么?
  • 2.安装和导入
    • 2.1 安装
    • 2.2 导入
  • 3.NumPy快速入门
    • 3.1 基础
      • 3.1.1 数组常用属性
      • 3.1.2 数组创建
        • 1) 创建一维数组
        • 2) 创建二维数组
        • 3) 在创建时指定数组的数据类型
        • 4) 创建特殊数组
        • 5) 创建某个范围内含有指定元素个数的数组
      • 3.1.3 打印数组
      • 3.1.4 基本运算
      • 3.1.5 通用函数
      • 3.1.6 索引、切片和遍历
        • 1) 一维数组索引、切片
        • 2) 二维数组索引、切片
        • 3) 遍历数组
    • 3.2 尺寸操作
      • 3.2.1 改变数组的尺寸
      • 3.2.2 数组组合
      • 3.2.3 数组拆分
    • 3.3 拷贝copy()和view()
      • 1) 无拷贝 =
      • 2) 浅拷贝 view()
      • 3) 深拷贝 copy()
    • 3.4 高级索引
      • 1) 使用布尔数组建立索引
    • 3.5 线性代数

1.NumPy是什么?

NumPy是用Python进行科学计算的基本库,它提供多维数组对象、各种派生对象(例如蒙版数组和矩阵)和各种数组快速运算的例行程序,包括数学、逻辑、尺寸操作、排序、选择、输入输出、离散傅里叶变换、基本线性代数、基本统计运算和随机模拟等等。

NumPy库的核心是ndarray对象,它封装了同类数据类型的n维数组,很多运算都是在编译过的代码中执行。NumPy和标准Python序列有以下几个重要区别:

  • NumPy数组创建时具有固定的大小,不像Python列表可以动态改变。
  • NumPy数组中的元素要求具有相同的数据类型,因此每个元素在内存中大小相同。(例外情况:一个包含(Python,包括NumPy)的对象,允许数组具有不同大小的元素。
  • NumPy数组有助于对大量数组进行高级数学运算和其他类型的运算。通常,与使用Python内置序列相比,这些运算能更高效的执行而且代码更少。
  • 越来越多基于Python的科学和数学包正在使用NumPy数组,尽管这些包通常支持Python序列输入,但它们会在处理之前把此类输入转换为NumPy数组,并且通常会输出NumPy数组。总之,为了有效使用如今基于Python的科学或数学软件,仅仅知道怎样使用Python内置序列是不够的,一个使用Python的人需要知道怎样使用NumPy数组。


2.安装和导入

2.1 安装

Windows系统下安装NumPy
Anaconda软件

# conda控制台安装
conda install numpy
# Windows控制台安装
pip install numpy    
pip3 install numpy

Pycharm软件

【科学计算和数据分析】numpy 第一篇——快速入门_第2张图片


2.2 导入

import numpy as np


3.NumPy快速入门

3.1 基础

3.1.1 数组常用属性

数组常用属性 说明
ndarray.ndim 数组维度 integer。
ndarray.shape 数组尺寸 (row,col)。
ndarray.size 数组元素个数。
ndarray.dtype 数组元素的数据类型。
ndarray.itemsize 数组每个元素所占内存大小(以字节为单位)。
import numpy as np

a = np.arange(15).reshape(3,5)  # 创建包含0~14的一维数组,并把尺寸更改为3×5
print(a)
"""
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
"""

print(a.shape)      # (3, 5)
print(a.ndim)       # 2
print(a.size)       # 15
print(a.dtype)      # int32
print(a.itemsize)   # 4
print(a.data)       # 
print(type(a))      # 


3.1.2 数组创建

有几种创建数组的方法。例如,你可以使用array()函数从常规的Python列表元组创建一个数组,可通过列表或元组中元素的数据类型来推断所得数组的元素数据类型。

1) 创建一维数组

import numpy as np

a = np.array([2,3,4])
print(a,a.dtype)  # [2 3 4] int32

b = np.array([1.2,3.5,5.1])
print(b,b.dtype)  # [1.2 3.5 5.1] float64

2) 创建二维数组

import numpy as np

a = np.array([(1.5,2,3), (4,5,6)])
print(a)
"""
[[1.5 2.  3. ]
 [4.  5.  6. ]]
"""

3) 在创建时指定数组的数据类型

import numpy as np

c = np.array( [ [1,2], [3,4] ], dtype=complex )
print(c)
"""
[[1.+0.j 2.+0.j]
 [3.+0.j 4.+0.j]]
"""

4) 创建特殊数组

方法 说明
np.zeros() 创建全0数组。
np.ones() 创建全1数组。
np.empty() 创建空数组,数组的元素是随机的。
import numpy as np

a1 = np.zeros(3)                    # 创建一维数组
print(a1,a1.dtype)  # [0. 0. 0.] float64
a2 = np.zeros((3,4),dtype="int32")  # 创建二维数组,数据类型指定为int32
print(a2)
"""
[[0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]]
"""

b = np.ones((2,3,4))  # 创建三维数组
print(b)
"""
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
"""

c = np.empty((2,3))
print(c)  
"""
[[6.23042070e-307 3.56043053e-307 1.37961641e-306]
 [6.23039354e-307 1.69115935e-306 0.00000000e+000]]
"""

5) 创建某个范围内含有指定元素个数的数组

import numpy as np

a = np.linspace(0,2,9)  # 在[0,2]线性产生含有9个元素的数组
print(a)
# [0.   0.25 0.5  0.75 1.   1.25 1.5  1.75 2.  ]


3.1.3 打印数组

打印方式 说明
print() 直接打印,当数据量非常大时会隐藏中间数据。
np.set_printoptions(threshold=sys.maxsize) 全部打印,通过这行代码声明打印时显示所有数据。
import numpy as np

print(np.arange(10000))
# [   0    1    2 ... 9997 9998 9999]
import sys
import numpy as np

np.set_printoptions(threshold=sys.maxsize)
print(np.arange(10000))

【科学计算和数据分析】numpy 第一篇——快速入门_第3张图片


3.1.4 基本运算

数组运算 说明
+-* 数组相加、相减、相乘。
+=-=*= 数组相加、相减、相乘。
@dot() 矩阵相乘(@适用于Python3.5以后的版本)。
numpy.max() 求数组元素最大值(可通过指定axis=0(按列)、axis=1(按行)求行或列的最大值)。
numpy.min() 求数组元素最小值(可通过指定axis=0(按列)、axis=1(按行)求行或列的最小值)。
numpy.sum() 数组求和(可通过指定axis=0(按行)、axis=1(按列)求行或列的和)。
numpy.cumsum() 数组求累加和(可通过指定axis=0(按行)、axis=1(按列)求行或列的累加和)。
import numpy as np

a = np.array( [20,30,40,50] )
b = np.arange(4)
c = a - b
d = b**2
print(a,b,sep="\n")
"""
[20 30 40 50]
[0 1 2 3]
"""
print(c)  # [20 29 38 47]
print(d)  # [20 29 38 47]

A = np.array( [[1,1],[0,1]] )
B = np.array( [[2,0],[3,4]] )
C1 = A * B           # elementwise product
C2 = A @ B           # matrix product (Python>=3.5)
C3 = A.dot(B)        # matrix product
print(C1,C2,C3,sep="\n\n")
"""
[[2 0]
 [0 4]]

[[5 4]
 [3 4]]

[[5 4]
 [3 4]]
"""

A *= 3
B += A
print(A)
"""
[[3 3]
 [0 3]]
"""
print(B)
"""
[[5 3]
 [3 7]]
"""

C = np.random.random((2,3))
print(C)
"""
[[0.72455309 0.57577621 0.6516948 ]
 [0.56008549 0.97001158 0.17850673]]
"""
print(C.sum())          # 3.66062790490271
print(C.min())          # 0.17850673463686328
print(C.max())          # 0.970011580490359
print(C.min(axis=0))    # [0.56008549 0.57577621 0.17850673]

D = np.arange(12).reshape(3,4)
print(D)
"""
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
"""
print(D.sum(axis=0))
# [12 15 18 21]
print(D.sum(axis=1))
# [ 6 22 38]
print(D.cumsum())  
# [ 0  1  3  6 10 15 21 28 36 45 55 66]
print(D.cumsum(axis=1))
"""
[[ 0  1  3  6]
 [ 4  9 15 22]
 [ 8 17 27 38]]
"""


3.1.5 通用函数

NumPy提供熟悉的数学函数,例如sin,cos和exp。在NumPy中,这些函数称为通用函数(ufunc),它们在数组上逐元素运算,生成一个数组作为输出。

import numpy as np

a = np.sin([np.pi/6,np.pi/2,np.pi])
print(a)  # [5.0000000e-01 1.0000000e+00 1.2246468e-16]

b1 = np.exp(np.arange(3))
b2 = np.exp([0,1,2])
print(b1)  # [1.         2.71828183 7.3890561 ]
print(b2)  # [1.         2.71828183 7.3890561 ]

c = np.sqrt(b2)
print(c)   # [1.         1.64872127 2.71828183]

d = np.add(b2,c)
print(d)   # [ 2.          4.3670031  10.10733793]


3.1.6 索引、切片和遍历

1) 一维数组索引、切片

NumPy的一维数组非常像Python中的列表和其他序列,可以被索引、切片和遍历。下面以Python一维列表的索引和切片方式来对NumPy一维数组进行索引和切片。

import numpy as np

a = np.arange(10)**3
print(a)        # [  0   1   8  27  64 125 216 343 512 729]

print(a[2])     # 8
print(a[-1])    # 729
print(a[1:4])   # [ 1  8 27]
print(a[2::])   # [  8  27  64 125 216 343 512 729]
print(a[0:-1])  # [  0   1   8  27  64 125 216 343 512]
print(a[::-1])  # [729 512 343 216 125  64  27   8   1   0]

2) 二维数组索引、切片

NumPy二维数组的索引和切片方式和MATLAB二维数组的索引和切片方式基本一致。

索引或切片方式 说明
a[m,n] 取数组a第m行第n列的元素。
a[i:j,k] 取数组a第i~第j-1行,第k列的元素。
a[k,i:j] 取数组a第i~第j-1列,第k行的元素。
a[i,:] 取数组a第i行所有列的元素。
a[:,j] 取数组a第j列所有行的元素。
a[i:j,k:q] 取数组a第i到第j-1行,第k到第q-1列的所有元素。
import numpy as np

def f(x,y):
    return 10*x + y

a = np.fromfunction(f, (5,4),dtype=int)
print(a)
"""
[[ 0  1  2  3]
 [10 11 12 13]
 [20 21 22 23]
 [30 31 32 33]
 [40 41 42 43]]
"""
print(a[2,3])     # 23
print(a[0:5,1])   # [ 1 11 21 31 41]
print(a[:,1])     # [ 1 11 21 31 41]
print(a[1:3,:])
"""
[[10 11 12 13]
 [20 21 22 23]]
"""

3) 遍历数组

import numpy as np

# 一维数组遍历
array = np.arange(5)
print(array)  # [0 1 2 3 4]
for a in array:
    print(a)
"""
0
1
2
3
4
"""

# 二维数组遍历
b = np.arange(10,16).reshape(2,3)
print(b)
"""
[[10 11 12]
 [13 14 15]]
"""
for row in b:   		# 按列表遍历方式遍历
    print(row)  		# b本质是一个ndarray类的对象,所以会直接输出数组本身
"""
[10 11 12]
[13 14 15]
"""
for element in b.flat:  # 先将数组扁平化为一维数组后再遍历
    print(element)
"""
10
11
12
13
14
15
"""


3.2 尺寸操作

3.2.1 改变数组的尺寸

方法 说明
ndarray.reshape() 改变数组的形状,返回副本。原数组的尺寸没有改变。
ndarray.resize() 直接改变原数组的尺寸。
import numpy as np

arr1 = np.array([0,1,2,3,4,5])
arr1.reshape(2,3)
print(arr1)  # [0 1 2 3 4 5]
arr2 = arr1.reshape(2,3)
print(arr2)
"""
[[0 1 2]
 [3 4 5]]
"""

arr1.resize(2,3)
print(arr1)
"""
[[0 1 2]
 [3 4 5]]
"""


3.2.2 数组组合

组合方式 说明
np.vstack((a,b)) 按纵向组合。
np.hstack((a,b)) 按横向组合。
import numpy as np

a = np.array([[9,7],[5,2]])
b = np.array([[1,9],[5,1]])
print(a)
"""
[[9 7]
 [5 2]]
"""
print(b)
"""
[[1 9]
 [5 1]]
"""

print(np.vstack((a,b)))
"""
[[9 7]
 [5 2]
 [1 9]
 [5 1]]
"""
print(np.hstack((a,b)))
"""
[[9 7 1 9]
 [5 2 5 1]]
"""


3.2.3 数组拆分

拆分方式 说明
np.vsplit(a,k) 纵向拆分。k为整数时,表示拆分为k个数组(要求k能被数组的行数整数);k为元组(m,m+1)时,表示以m列为间隔拆分。
np.hsplit(a,k) 横向拆分。k取值同理。
import numpy as np

a = np.arange(24).reshape(2,12)
print(a)
"""
[[ 0  1  2  3  4  5  6  7  8  9 10 11]
 [12 13 14 15 16 17 18 19 20 21 22 23]]
"""
print((np.hsplit(a,3)))
"""
[array([[ 0,  1,  2,  3],
       [12, 13, 14, 15]]), array([[ 4,  5,  6,  7],
       [16, 17, 18, 19]]), array([[ 8,  9, 10, 11],
       [20, 21, 22, 23]])]
"""

print(np.hsplit(a,(3,4))) 
"""
[array([[ 0,  1,  2],
       [12, 13, 14]]), array([[ 3],
       [15]]), array([[ 4,  5,  6,  7,  8,  9, 10, 11],
       [16, 17, 18, 19, 20, 21, 22, 23]])]
"""


3.3 拷贝copy()和view()

拷贝方式 说明
= 无拷贝(相当于给对象的引用起了一个别名)。
view() 浅拷贝(产生新对象,与原对象共享内存)。
copy() 深拷贝(产生新对象和新内存)。

1) 无拷贝 =

import numpy as np

a = np.arange(12)
b = a
print(id(a))  # 2264262477664
print(id(b))  # 2264262477664  没有产生新对象

b.resize(2,6) # a和b本质为同一个对象,b改变,a也随着改变
print(a)
"""
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]
"""

2) 浅拷贝 view()

import numpy as np

a = np.arange(12).reshape(3,4)
b = a.view()
print(id(a))   # 2264262871600
print(id(b))   # 2264262872880  产生新对象

b[0,2] = 1234  # 直接修改内存中数组的数据,所以a也改变
print(a)
"""
[[   0    1 1234    3]
 [   4    5    6    7]
 [   8    9   10   11]]
"""

3) 深拷贝 copy()

import numpy as np

a = np.arange(12).reshape(3,4)
b = a.copy()
print(id(a))  # 2264262500144
print(id(b))  # 2264242768192  产生新对象

b[0,2] = 1234
print(a)      # 数组a没有改变
"""
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
"""
print(b)      # 产生新内存,修改数组b的数据不影响数组a
"""
[[   0    1 1234    3]
 [   4    5    6    7]
 [   8    9   10   11]]
"""


3.4 高级索引

1) 使用布尔数组建立索引

import numpy as np

a = np.arange(12).reshape(3,4)
b1 = np.array([False,True,True])
b2 = np.array([True,False,True,False])
print(a)
"""
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
"""

print(a[b1,:])   # 取数组a第1行和第2行的所有列的数据
"""
[[ 4  5  6  7]
 [ 8  9 10 11]]
"""

print(a[b1,b2])  # 取数组a第1行~第2行,第0列和第2列的数据
"""
[ 4 10]
"""


3.5 线性代数

import numpy as np

a = np.array([[1.0, 2.0], [3.0, 4.0]])
a.transpose()  # 将数组a转置
print(a)
"""
[[1. 2.]
 [3. 4.]]
"""

b = np.linalg.inv(a)  # 对转置后的数组a求逆
print(b)
"""
[[-2.   1. ]
 [ 1.5 -0.5]]
"""

c = np.array([[2,1],[-1,1]])
print(c @ c)   # 矩阵相乘
"""
[[ 3  3]
 [-3  0]]
"""

x = np.array([[1.0, 2.0], [3.0, 4.0]])
y = np.array([[5],[7]])
print(np.linalg.solve(x,y))  # 解线性方程
"""
[[-3.]
 [ 4.]]
"""

print(np.linalg.eig(x))  # 求特征值和特征向量
"""
(array([-0.37228132,  5.37228132]), array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]]))
"""

你可能感兴趣的:(python第三方库)