4.1 NumPy的ndarray:一种多维数组对象
4.1.1 创建ndarray
最基本的创建ndarray方法,用np.array直接指定内容及数据类型。
In [33]: arr1 = np.array([1, 2, 3], dtype=np.float64)
除此之外,还可以用以下一些特殊方法创建ndarray:
In [13]: data = np.random.randn(2, 3)
In [14]: data
Out[14]:
array([[-0.2047, 0.4789, -0.5194],[-0.5557, 1.9658, 1.3934]])In [30]: np.zeros((3, 6))
Out[30]:
array([[ 0., 0., 0., 0., 0., 0.],[ 0., 0., 0., 0., 0., 0.],[ 0., 0., 0., 0., 0., 0.]])In [31]: np.empty((2, 3, 2))
Out[31]:
array([[[ 0., 0.],[ 0., 0.],[ 0., 0.]],[[ 0., 0.],[ 0., 0.],[ 0., 0.]]])In [32]: np.arange(15)
Out[32]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
注意数据类型np.string_有一个下划线
In [44]: numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
4.1.2 ndarray的属性
ndarray有一些属性(ndim、shape、dtype)
In [25]: arr2.ndim
Out[25]: 2
In [26]: arr2.shape
Out[26]: (2, 4)
In [27]: arr1.dtype
Out[27]: dtype('float64')
4.1.3 转变ndarray数据类型
用astype方法转变ndarray数据类型。
In [41]: arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
In [43]: arr.astype(np.int32)
Out[43]: array([ 3, -1, -2, 0, 12, 10], dtype=int32)In [46]: int_array = np.arange(10)
In [47]: calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
In [48]: int_array.astype(calibers.dtype)
Out[48]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
4.1.4 利用切片修改数组元素
In [60]: arr = np.arange(10)
In [61]: arr
Out[61]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])# 可以把列表中多个值改成同一个值
In [64]: arr[5:8] = 12
In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])# 如果不是改成同一个值,那切片元素个数应该与等号右边给出的列表元素个数一样多。
In [64]: arr[:3]=[10,11,12]
In [65]: arr
Out[65]: array([10, 11, 12, 3, 4, 5, 6, 7, 8, 9])
4.1.5 数组切片修改
数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。
In [65]: arr
Out[65]: array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In [66]: arr_slice = arr[5:8]
In [67]: arr_slice
Out[67]: array([12, 12, 12])
In [68]: arr_slice[1] = 12345
In [69]: arr
Out[69]: array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
4.1.6 布尔值索引
In [98]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
In [99]: data = np.random.randn(7, 4)
In [100]: names
Out[100]:
array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],dtype='<U4')
In [101]: data
Out[101]:
array([[ 0.0929, 0.2817, 0.769 , 1.2464],[ 1.0072, -1.2962, 0.275 , 0.2289],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 1.669 , -0.4386, -0.5397, 0.477 ],[ 3.2489, -1.0212, -0.5771, 0.1241],[ 0.3026, 0.5238, 0.0009, 1.3438],[-0.7135, -0.8312, -2.3702, -1.8608]])
利用布尔值对data取相应列,有一定的意义,如果这里可以当成选出“Bob”列的数据。
In [107]: data[~(names == 'Bob')]
Out[107]:
array([[ 1.0072, -1.2962, 0.275 , 0.2289],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 3.2489, -1.0212, -0.5771, 0.1241],[ 0.3026, 0.5238, 0.0009, 1.3438],[-0.7135, -0.8312, -2.3702, -1.8608]])
要选择除”Bob”以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:
In [106]: names != 'Bob'
Out[106]: array([False, True, True, False, True, True, True], dtype=bool)
In [107]: data[~(names == 'Bob')]
Out[107]:
array([[ 1.0072, -1.2962, 0.275 , 0.2289],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 3.2489, -1.0212, -0.5771, 0.1241],[ 0.3026, 0.5238, 0.0009, 1.3438],[-0.7135, -0.8312, -2.3702, -1.8608]])
选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可:
In [110]: mask = (names == 'Bob') | (names == 'Will')
In [111]: mask
Out[111]: array([ True, False, True, True, True, False, False], dtype=bool)
In [112]: data[mask]
Out[112]:
array([[ 0.0929, 0.2817, 0.769 , 1.2464],[ 1.3529, 0.8864, -2.0016, -0.3718],[ 1.669 , -0.4386, -0.5397, 0.477 ],[ 3.2489, -1.0212, -0.5771, 0.1241]])
4.1.7 花式索引
如下面代码所示,有很多取值的方法。
In [122]: arr = np.arange(32).reshape((8, 4))
In [123]: arr
Out[123]:
array([[ 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]])In [124]: arr[[3,5,2,1]]
Out[124]: array([[12, 13, 14, 15],[20, 21, 22, 23],[ 8, 9, 10, 11],[ 4, 5, 6, 7]])In [124]: arr[[1, 5, 7, 2], [0, 3, 1, 2]]
Out[124]: array([ 4, 23, 29, 10])In [125]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]
Out[125]:
array([[ 4, 7, 5, 6],[20, 23, 21, 22],[28, 31, 29, 30],[ 8, 11, 9, 10]])
4.2 通用函数:快速的元素级数组函数
4.2.1 介绍了一些函数
# 自然对数e的次方,这里的arr的dtype应为float,下面的sqrt也是,不然会报错
np.exp(arr)# 开方
np.sqrt(arr)# 求两组相同结构array最大值(x、y多维的也行,也能直接用大于小于号比较得到相同结构的布尔值)
np.maximum(x, y)# 分开整数部分和小数部分
remainder, whole_part = np.modf(arr)# 把开方后的结果赋给arr,exp等其他函数也可以。
np.sqrt(arr, arr)
4.3 利用数组进行数据处理
4.3.1 where的应用
np.where()
的第一个参数应为布尔数组(可以通过条件判断生成,或直接传入布尔值)。当布尔值为 True
时,取第二个参数的值;当为 False
时,取第三个参数的值。第二和第三个参数可以是数组或标量。
In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
In [167]: cond = np.array([True, False, True, True, False])In [170]: result = np.where(cond, xarr, yarr)
In [171]: result
Out[171]: array([ 1.1, 2.2, 1.3, 1.4, 2.5])
4.3.2 数学和统计方法(sum、mean等)
这里主要就是axis轴的应用,我的记法是合(0)纵连(1)横,即axis=0,就在纵向进行数学操作,加减乘除啥的,axis=1,就是横向。
比如下图arr.mean(1),就是在横向进行数学运算,每一行得到一个平均值,最后返回一个长度为行数的数组。
In [177]: arr = np.random.randn(5, 4)
In [178]: arr
Out[178]:
array([[ 2.1695, -0.1149, 2.0037, 0.0296],[ 0.7953, 0.1181, -0.7485, 0.585 ],[ 0.1527, -1.5657, -0.5625, -0.0327],[-0.929 , -0.4826, -0.0363, 1.0954],[ 0.9809, -0.5895, 1.5817, -0.5287]])In [182]: arr.mean(axis=1)
Out[182]: array([ 1.022 , 0.1875, -0.502 , -0.0881, 0.3611])
In [183]: arr.sum(axis=0)
Out[183]: array([ 3.1693, -2.6345, 2.2381, 1.1486])
np.cunsum()累加、np.cumpod()累乘。
4.3.3 布尔值数组
用到了any()、all(),以及对布尔值True的求个数sum()。
In [190]: arr = np.random.randn(100)
In [191]: (arr > 0).sum() # Number of positive values
Out[191]: 42In [192]: bools = np.array([False, False, True, False])
In [193]: bools.any()
Out[193]: True
In [194]: bools.all()
Out[194]: False
4.3.4 sorted()函数总是返回列表
In [210]: sorted(set(names))
Out[210]: ['Bob', 'Joe', 'Will']
4.3.5 in1d函数
函数np.in1d用于测试一个数组中的值在另一个数组中的成员资格,返回一个布尔型数组。
In [211]: values = np.array([6, 0, 0, 3, 2, 5, 6])
In [212]: np.in1d(values, [2, 3, 6])
Out[212]: array([ True, False, False, True, True, False, True], dtype=bool)
4.4 用于数组的文件输入输出
4.4.1 save、load函数
save、load函数用于标准的单个array数组存储和加载
In [213]: arr = np.arange(10)
In [214]: np.save('some_array', arr)In [215]: np.load('some_array.npy')
Out[215]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
4.4.2 savez函数
np.savez可以将多个数组保存到一个未压缩文件中,将数组以关键字参数的形式传入即可;加载后配合表名可以得到该表数组内容。
In [216]: np.savez('array_archive.npz', a=arr, b=arr)In [217]: arch = np.load('array_archive.npz')
In [218]: arch['b']
Out[218]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
4.4.3 numpy.savez_compressed函数
如果要将数据压缩,可以使用numpy.savez_compressed:(加载方式和savez一样)
In [219]: np.savez_compressed('arrays_compressed.npz', a=arr, b=arr)
4.5 线性代数
4.5.1 相关函数
矩阵相乘用dot或符号@,需满足矩阵相乘的条件(懂得都懂)。
In [216]: x.dot(y)In [217]: np.dot(x, y)In [218]: x @ y
inv()用于求逆,需从numpy.linalg引入
from numpy.linalg import inv, qrinv(mat)
4.6 伪随机数生成
4.6.1 随机种子
我们说这些都是伪随机数,是因为它们都是通过算法基于随机数生成器种子,在确定性的条件下生成的。
np.random.seed()
是一个用于设置 全局随机数生成器的种子 的函数。它会影响到所有使用 np.random
模块生成的随机数。
import numpy as npnp.random.seed(1234)
print(np.random.rand(3)) # 生成3个随机数
np.random.RandomState()
是一个创建独立随机数生成器实例的方式。与 np.random.seed()
不同,RandomState
不影响全局的随机数生成器,它提供了一个独立的随机数生成器,你可以在多个地方使用不同的 RandomState
实例来生成随机数,而不会相互干扰。
import numpy as np# 创建一个独立的随机数生成器
random_gen = np.random.RandomState(1234)
print(random_gen.rand(3)) # 使用这个生成器生成3个随机数
np.random.seed()
:用于设置全局的随机数种子,影响整个np.random
模块的随机数生成。设置后,所有的随机数生成操作都会基于这个种子,可用于确保全局随机数的可重复性。np.random.RandomState()
:用于创建独立的随机数生成器实例,它不会影响全局的np.random
模块,适用于需要多个相互独立的随机数生成器的场景。
4.7 示例:随机漫步
4.7.1 argmax()、abs()函数
abs()函数求绝对值用的。
argmax()函数用来返回指定数组中最大值的索引。(在布尔值数组中,True就是最大值)
4.8 np.random生成函数
在 np.random
模块中,Numpy 提供了丰富的随机数生成函数,这些函数可以用来生成各种类型的随机数据。这些函数包括生成均匀分布、正态分布、二项分布等经典的随机分布数据,适用于许多科学计算、数据分析、机器学习和其他领域。以下是一些经典的生成函数:
4.8.1 np.random.rand()
np.random.rand()
:生成 [0, 1) 范围内的均匀分布的随机数(浮点数)。可以生成标量或多维数组。
np.random.rand(3) # 生成 3 个 [0, 1) 范围内的随机数
np.random.rand(2, 3) # 生成一个 2x3 的随机数矩阵
np.random.uniform(low, high, size)
:生成 [low, high) 范围内均匀分布的随机数。可以指定随机数的范围。
np.random.uniform(1, 10, 5) # 生成 5 个 [1, 10) 范围内的随机数
4.8.2 生成正态分布(高斯分布)的随机数
np.random.randn()
:生成标准正态分布(均值 0,方差 1)的随机数,类似于 rand()
,但生成正态分布的随机数。
np.random.randn(4) # 生成 4 个标准正态分布的随机数
np.random.randn(2, 3) # 生成一个 2x3 的正态分布矩阵
np.random.normal(loc, scale, size)
:生成指定均值 loc
和标准差 scale
的正态分布随机数。
np.random.normal(0, 1, 5) # 生成 5 个均值为 0,标准差为 1 的随机数
np.random.normal(10, 3, (2, 3)) # 生成一个 2x3 的矩阵,随机数来自均值 10、标准差 3 的正态分布
4.8.3 生成整数随机数
np.random.randint(low, high, size)
:生成 [low, high) 范围内的随机整数。如果只指定 low
,则生成 [0, low) 的随机整数。
np.random.randint(1, 10, 5) # 生成 5 个 [1, 10) 之间的随机整数
np.random.randint(0, 100, (3, 3)) # 生成一个 3x3 的随机整数矩阵
4.8.4 生成二项分布随机数
np.random.binomial(n, p, size)
:生成二项分布的随机数,n
是试验次数,p
是每次成功的概率。
np.random.binomial(10, 0.5, 5) # 生成 5 个样本,每个样本由 10 次试验组成,成功概率为 0.5