numpy 使用

简介

NumPy(Numerical Python)是 Python 中用于科学计算的核心库,专注于高效处理多维数组(矩阵)和提供大量数学运算函数,是数据分析、机器学习、科学计算等领域的基础工具。

在NumPy包的核心是ndarray对象。该对象封装了具有同质数据类型的n维数组,并且为了提高性能,许多操作都是通过编译代码执行的。

  • 高效的多维数组对象(ndarray)

    • 同构数据的多维容器(所有元素类型相同),比 Python 内置的列表(list)运算速度快得多(底层用 C 实现)。
    • 支持自定义维度(1D 向量、2D 矩阵、3D 张量等)。
  • 丰富的数学运算函数

    • 提供矩阵运算(加减乘除、转置、求逆等)、统计分析(均值、方差、求和等)、线性代数、傅里叶变换等功能。
  • 广播机制(Broadcasting)

    • 允许不同形状的数组之间进行算术运算(自动扩展维度以匹配),简化代码。
  • 与其他库的兼容性
    是 Pandas、Matplotlib、Scikit-learn 等数据科学库的基础,数据格式可无缝互通。

安装

pip install numpy

广播机制

广播的第一条规则是,如果所有输入数组的维度数量不同,那么会在较小数组的形状前反复添加 “1”,直到所有数组的维度数量相同。
广播的第二条规则确保,在某一特定维度上大小为1的数组,其行为就好像它在该维度上的大小与形状最大的数组相同。对于 “广播” 数组,假定该数组元素在该维度上的值是相同的。

数据类型

要转换数组的类型,请使用.astype()方法

z.astype(np.float64)

数据类型对象

import numpy as np 
a= np.dtype(np.int64) 
print(a)  
# int64

数据类型标识码

字符对应类型
b代表布尔型
i带符号整型
u无符号整型
f浮点型
c复数浮点型
m时间间隔(timedelta)
Mdatatime(日期时间)
OPython对象
S,a字节串(S)与字符串(a)
UUnicode
V原始数据(void)

数值数据类型

有5种基本数值类型,分别表示布尔值(bool)、整数(int)、无符号整数(uint)、浮点数(float)和complex。

字符串和字节的数据类型

NumPy 还支持存储 Unicode 字符串,通过 numpy.str_ 数据类型(U 字符代码)存储,通过 numpy.bytes_(S 字符代码)存储以空字符结尾的字节序列,以及通过 numpy.void(V 字符代码)存储任意字节序列。

np.array(["hello", "world!"])

ndarray

属性

  • data: 包含数组实际元素的缓冲区
  • itemsize: 数组中每个元素的字节大小
  • dtype:一个描述数组中元素类型的对象
  • size:数组元素的总数。这等于shape的元素的乘积。
  • shape : 数组的维度。这是一个整数元组,表示数组在每个维度上的大小。
  • ndim: 数组的轴(维度)数量。

创建

默认情况下,创建的数组的数据类型为float64,但可以通过关键字参数dtype指定。

arange

import numpy as np
a = np.arange(15).reshape(3, 5)

当使用带有浮点参数的arange时,由于浮点精度有限,通常无法预测得到的元素数量。因此,通常最好使用函数linspace,它接收我们想要的元素数量作为参数,而不是步长。

linspace

np.linspace(0, 2, 9)

array

np.array([1, 2, 3]) # 一维数组
np.array([(1.5, 2, 3), (4, 5, 6)]) # 二维数组
np.array([[1, 2], [3, 4]], dtype=complex) # 指定类型

zeros & ones & empty

np.zeros((3, 4))
np.ones((2, 3, 4), dtype=np.int16)
np.empty((2, 3)) 

zeros_like & ones_like & empty_like

a = np.arange(10).reshape(2, 5)
b = np.ones_like(a)

eye & diag & vander

np.eye(3) # 三维单位阵

numpy.diag 既可以定义一个主对角线为给定值的二维方阵,也可以在传入二维数组时,返回一个仅包含对角线元素的一维数组。

np.diag([1, 2, 3]) # 主对角线未1,2,3 的方阵

np.diag([1, 2, 3], 1)  # 向主对角线右上方偏移1

a = np.array([[1, 2], [3, 4]])
np.diag(a)

vander(x, n) 将范德蒙德矩阵定义为一个二维NumPy数组。范德蒙德矩阵的每一列都是输入的一维数组、列表或元组 x 的降幂,其中最高多项式阶数为 n-1。此数组创建例程在生成线性最小二乘模型时很有用。

np.vander((1, 2, 3, 4), 4)

random

a = np.random.randint((3,4))

indices

numpy.indices 会创建一组数组(堆叠成一个高一维的数组),每个维度对应一个数组,每个数组表示该维度上的变化:

np.indices((3,3))
"""
array([[[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2]],
       [[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]])
"""

从文件读取

np.loadtxt('simple.csv', delimiter = ',', skiprows = 1) 

np.fromfunction

def f(x, y):
    return 10 * x + y
# 创建一个5*4的数组,x,y 的值是根据当前的行和列的序号,0开始
b = np.fromfunction(f, (5, 4), dtype=int)
array([[ 0,  1,  2,  3],
       [10, 11, 12, 13],
       [20, 21, 22, 23],
       [30, 31, 32, 33],
       [40, 41, 42, 43]])

基本运算

a = np.array([20, 30, 40, 50])
b = np.arange(4)
c = a - b

b**2
10 * np.sin(a)

a < 35 # 返回bool

a *= 3  # 就地修改,而不是创建新的
b += a

# 当使用不同类型的数组进行操作时,结果数组的类型对应于更通用或更精确的类型
d = np.linspace(0, 7, 4)
b + d

在NumPy数组中,乘法运算符 * 按元素进行运算。矩阵乘法可以使用 @ 运算符(在Python >=3.5中)或 dot 函数或方法来执行

A = np.array([[1, 1],
              [0, 1]])
B = np.array([[2, 0],
              [3, 4]])
A * B    
A @ B    
A.dot(B)  

索引 & 切片 & 迭代

如果索引值超出范围,则会引发 IndexError

一维数组

a = np.arange(10)**3
a[2]
a[2:5]
a[:6:2] = 500  # 前6个 每个两个修改值为500
a[::-1] # 翻转

多维数组

b = np.arange(20).reshape(5,4)
b[2, 3]  # 第三行,第四列
b[0:5, 1] # 第二列
b[:, 1]  # 第二列
b[1:3, :]
b[-1]  # 最后一行

...

# 如果 x 是一个具有 5 个轴的数组
x[1, 2, ...] 等效于 x[1, 2, :, :, :]
x[..., 3] 等同于 x[:, :, :, :, 3]
x[4, ..., 5, :] 等同于 x[4, :, :, 5, :]

整数数组索引

x = np.arange(10, 1, -1)
x[np.array([3, 3, 1, 8])]

# 一维度
x = np.array([[1, 2], [3, 4], [5, 6]])
x[[0, 1, 2], [0, 1, 0]]   # (0,0), (1,0), (2,0) 的值

# 多维度
rows = np.array([0, 3], dtype=np.intp)
columns = np.array([0, 2], dtype=np.intp)
x[rows[:, np.newaxis], columns]   # 获取(0, 0), (0, 2), (3, 0), (3, 2) 的值

# 使用ix_ 可实现类似的效果
x[np.ix_(rows, columns)]

布尔数组索引

x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]])
x[~np.isnan(x)]

x = np.array([1., -1., -2., 3])
x[x < 0] += 20

x = np.arange(35).reshape(5, 7)
b = x > 20
x[b[:, 5]]  # 获取最后两行的值

迭代

对多维数组进行迭代是按照第一轴进行的

for row in b:
    print(row)

如果想要对数组中的每个元素执行操作,可以使用 flat 属性,它是一个遍历数组所有元素的 迭代器:

for element in b.flat:
    print(element)

形状操作

查看

方法描述
ndarray.flags有关数组内存布局的信息。
ndarray.shape数组维度的元组。
ndarray.strides遍历数组时每个维度中的字节元组。
ndarray.ndim数组维数。
ndarray.dataPython缓冲区对象指向数组的数据的开头。
ndarray.size数组中的元素数。
ndarray.itemsize一个数组元素的长度,以字节为单位
ndarray.nbytes数组元素消耗的总字节数。
ndarray.base如果内存来自其他对象,则为基础对象。

ravel

a.ravel()  # returns the array, flattened

让多维数组变成一维数组

返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)

不会改变原数组的形状

reshape

不会改变原数组的形状

a.reshape(6, 2)  # returns the array with a modified shape
# 如果在重塑操作中某个维度被指定为 -1,则其他维度会自动计算
a.reshape(3, -1)

reshape能够帮助用户把原数组按照新的维度重新排列。在使用时有两种模式,分别为C模式和F模式,分别以逐行和逐列的顺序进行填充读取

a.reshape((4,2), order='C')
a.reshape((4,2), order='F')

.T

不会改变原数组的形状
转置

a.T  # returns the array, transposed

base

如果一个ndarray是通过其他ndarray经过某种操作创建出来的,那么其base就会指向最初的源头。

a = np.arange(20)
b = a.reshape(2,5,2)
print(b.base)  # [1-20]

strides

ndarray的每一个维度(axis)都有一个strides,表示从数组在某个维度进行遍历的内存偏移量

a = np.arange(24).reshape([2, 3, 4])

print(a.strides)  # ==> (48, 16, 4)

flat

返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。

flatten

flatten: 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。

broadcast

broadcast 生成一个模拟广播的对象。

broadcast_to

broadcast_to 将数组广播为新的形状。

expand_dims

expand_dims(arr, axis) 扩展数组的形状。

squeeze

squeeze(arr, axis)

  • 删除数组中维度为 1 的项
  • 指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。

trnaspose

transpose(,axes=())
改变了数组的维度(axis)排列顺序。
transpose操作只是改变了strides的顺序,没有重新排列内存中的数据。

transpose([0, 1, 2]): 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。

rollaxis

rollaxis(arr. axis, start): 沿着指定的轴向后滚动至规定的位置。

swapaxes

swapaxes(arr. axis1, axis2): 对数组的轴进行对换。

resize

修改数组本身

a.resize((2, 6))

扩维

rows = np.array([0, 3], dtype=np.intp)
rows[:, np.newaxis]  # 2, 1

堆叠

vstack & hstack

a = np.floor(10 * rg.random((2, 2)))
b = np.floor(10 * rg.random((2, 2)))
np.vstack((a, b)) # 垂直堆叠,加在行上
np.hstack((a, b)) # 水平堆叠,加在列上

对于超过二维的数组,hstack 沿着其第二轴堆叠,vstack 沿着其第一轴堆叠.

hstack & column_stack

函数column_stack 将一维数组按列堆叠成二维数组。仅对于二维数组,它等同于hstack

np.column_stack((a, b))
a = np.array([4., 2.])
b = np.array([3., 8.])

np.column_stack((a, b))
"""
array([[4., 3.],
       [2., 8.]])
"""
np.hstack((a, b)) 
# array([4., 2., 3., 8.])

concatenate

沿指定轴连接两个或者多个相同形状的数组

numpy.concatenate((a1, a2, ...), axis):

stack 沿着新的轴连接一系列数组

r_ & c_

np.r_[]: 行,上下

np.c_[]: 列, 左右

np.r_[1:4, 0, 4]
a = np.array([[1, 2, 3],[7,8,9]])
b=np.array([[4,5,6],[1,2,3]])

np.c_[a, b]
"""
array([[1, 2, 3, 4, 5, 6],
       [7, 8, 9, 1, 2, 3]])
"""

np.r_[a, b]
"""
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6],
       [1, 2, 3]])
"""

分割

split

numpy.split(ary, indices_or_sections, axis)`将一个数组分割为多个子数组

  • indices_or_sections:

    • 若是一个整数,代表用该整数平均切分,

    • 若是一个数组,则代表沿轴切分的位置(左开右闭)

  • axis:默认为0,表示横向切分;为1时表示纵向切分

hsplit

使用 hsplit,你可以沿水平轴拆分数组,既可以指定要返回的形状相同的数组数量,也可以指定拆分应在哪些列之后进行

a = np.floor(10 * rg.random((2, 12)))
np.hsplit(a, 3) # 拆分成3个
np.hsplit(a, (3, 4)) # 拆分成3个,第3列分割,第4列分割

vsplit

vsplit 沿垂直轴拆分

array_split

array_split 允许指定沿哪个轴拆分。

复制

完全不复制

简单赋值不会复制对象或其数据。

a = np.floor(10 * rg.random((2, 12)))
b = a
b is a     # True      # a and b are two names for the same ndarray object

# 引用传递参数
def f(x):
    print(id(x))
id(a)
f(a)

视图或浅拷贝

不同的数组对象可以共享相同的数据。view 方法创建一个新的数组对象,该对象查看相同的数据。

c = a.view()
c is a            # False
c.base is a       # True 
c.flags.owndata   # False

c = c.reshape((2, 6))
a.shape 		# 未改变

c[0, 4] = 1234
a				# a的值修改

切片数组会返回其视图

s = a[:, 1:3]
s[:] = 10
a

深拷贝

copy方法会对数组及其数据进行完整的复制。

d = a.copy()
d is a  # False

d[0, 0] = 9999
a       # 未修改

通用函数

NumPy提供了常见的数学函数, 这些函数对数组进行逐元素操作,并输出一个数组。

a = np.arange(3)
np.exp(a)
np.sqrt(a)

一元
在这里插入图片描述
二元
在这里插入图片描述

统计

b = np.arange(12).reshape(3, 4)
b.sum()		      # sum all element
b.sum(axis=0)     # sum of each column
b.min(axis=1)     # min of each row
b.cumsum(axis=1)  # cumulative sum along each row

b.argmin() # 返回最小值索引
b.argmax()

数组的集合操作

  • unique(x):唯一值
  • intersect1d(x, y): 交集
  • union1d(x, y) : 并集
  • in1d(x, y):查看x的元素是否包含在y中,返回一个布尔数组
  • setdiff1d(x, y):差集
  • setxor1d(x, y): 异或

随机数

在这里插入图片描述

choice

choice可以从给定的列表中,以一定概率和方式抽取结果,当不指定概率时为均匀采样,默认抽取方式为有放回抽样:

my_list = ['a', 'b', 'c', 'd']
np.random.choice(my_list, 2, replace=False, p=[0.1, 0.7, 0.1 ,0.1])
"""
array(['b', 'a'], dtype='<U1')
"""


np.random.choice(my_list, (3,3))
"""
array([['c', 'b', 'd'],
       ['d', 'a', 'd'],
       ['a', 'c', 'd']], dtype='<U1')
"""

permutation

当返回的元素个数与原列表相同时,不放回抽样等价于使用permutation函数,即打散原列表:

np.random.permutation(my_list)

线型代数

numpy.linalg
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值