学习目标
掌握ndarray多维数组的创建
掌握数组元素的索引、切片和选择
掌握数组的运算
掌握读写数据文件
NumPy简介
NumPy是在1995年诞生的Python库Numeric的基础上建立起来的,但真正促使NumPy的发行的是Python的SciPy库。SciPy中并没有合适的类似于Numeric中的对于基础数据对象处理的功能,于是,SciPy的开发者将SciPy中的一部分和Numeric的设计思想结合,在2005年发行了NumPy。
NumPy(Numerical Python的缩写)是一个开源的Python科学计算和数据分析的扩展库,包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能,是很多数据分析扩展库的基础库。
NumPy允许用户进行快速的交互式原型设计,可以很自然地使用数组和矩阵。
NumPy的部分功能如下:
- ndarrray:一个具有矢量算术运算且节省空间的多维数组。
- 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。
- 用于读/写磁盘数据的工具以及用于操作内存映射文件的工具。
- 线性代数、随机数生成以及傅里叶变换功能。
-
NumPy多维数组
NumPy提供了两种基本的对象:
ndarray:英文全称为n-dimensional array object,称为多维数组,后统一称之为数组。
- ufunc:英文全称为universal function object,它是一种能够对数组进行处理的特殊函数。
NumPy库的核心对象是n维数组对象ndarray,Python中所有的ufunc函数都是围绕ndarray对象进行的。
- ndarray数组能够对整块数据进行数学运算
- 通常来说,ndarray是存储单一数据的容器,即其中的所有元素都需要是相同的类型
- 和list不同,它能直接保存数据,而list保存的是对象的引用。
Numpy常用的导入格式:import numpy as np
。
NumPy库的基础是n维数组对象(即ndarray对象),该对象由两部分组成:
- 一部分是实际的数据(同种类型)
- 另一部分是描述这些数据的元数据
ndarray数组中的维度(dimensions)又称为轴(axis)。
数组的第0轴对应着第一维,第1轴对应着第二维,维度为(3, 4)的形状,元素总个数为12。
创建ndarray对象
1. 利用array函数创建数组对象
array函数的格式:np.array(object, dtype, ndmin)
array函数的主要参数及说明表:
参数名称 | 说明 |
---|---|
object | 接收array,表示想要创建的数组 |
dtype | 接收data-type,表示数组需要的数据类型,未给定则选择保存对象所需最小类型,默认为None |
ndmin | 接收int,指定生成数组应该具有的最小维度,默认为None |
import numpy as np
# 列表
data1 = [1, 3, 5, 7]
w1 =np.array(data1)
print('w1:', w1)
# 元组
data2 = (2, 4, 6, 8)
w2 = np.array(data2)
print('w2:', w2)
# 多维数组
data3 = [[1, 2, 3, 4], [5, 6, 7, 8]]
w3 = np.array(data3)
print('w3:', w3)
'''
w1: [1 3 5 7]
w2: [2 4 6 8]
w3: [[1 2 3 4]
[5 6 7 8]]
'''
2. 专门创建数组的函数
arange
函数创建等差一维函数。
格式:np.arange([start, ]stop, [step, ]dtype)
参数名称 | 说明 |
---|---|
start | 起始值,默认从0开始 |
stop | 结束值,生成的元素不包括结束值 |
step | 步长,可省略,默认步长为1 |
dtype | 设置元素的数据类型,默认使用输入数据的类型 |
warray = np.arange(20)
print(warray)
warray = np.arange(0, 1, 0.2)
print(warray)
'''
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
[0. 0.2 0.4 0.6 0.8]
'''
linspace
函数创建等差一维数组,接收元素数量作为参数。
格式:np.linspace(start, stop, num, endpoint, retstep = False, dtype = None)
参数名称 | 说明 |
---|---|
start | 起始值,默认从0开始 |
stop | 结束值,生成的元素不包括结束值 |
num | 要生成的等间隔样例数量 |
warray = np.linspace(0, 1, 5)
print(warray)
'''
[0. 0.25 0.5 0.75 1. ]
'''
logspace
函数:创建等比一维数组
格式:np.logspace(start, stop, num, endpoint = True, base = 10.0, dtype = None)
参数名称 | 说明 |
---|---|
start,stop | 代表的是10的幂,默认基数base为10 |
num | 要生成的元素个数 |
# 生成1-10之间的具有5个元素的等比数列
warray = np.logspace(0, 1, 5)
print(warray)
'''
[ 1. 1.77827941 3.16227766 5.62341325 10. ]
'''
zeros
函数:创建指定长度或形状的全0数组
格式:np.zeros(shape, dtype = float, order = 'C')
ones
函数:创建指定长度或形状的全1数组
格式:np.ones(shape, dtype = None, order = 'C')
empty()
函数:创建一个随机数组
格式:np.empty(shape, dtype = float, order = 'C')
eye()
函数创建一个对角线全1,其余位置全是0的二维数组
格式:eye(N, M = None, k = 0)
说明:
- N:行数
- M:可选参数,列数,默认值为N
- k:k = 0时,全1对角线为主对角线;k > 0时,全1对角线向右上方偏移;k < 0时,全1对角线向左下方偏移。 ```python import numpy as np arr1 = np.zeros(shape = (2, 2)) arr2 = np.ones(shape = (2, 2)) arr3 = np.empty(shape = (3, 3)) arr4 = np.eye(3) print(arr1) print(arr2) print(arr3) print(arr4)
‘’’ [[0. 0.] [0. 0.]] [[1. 1.] [1. 1.]] [[0.00000000e+000 0.00000000e+000 0.00000000e+000] [0.00000000e+000 0.00000000e+000 6.00783825e-321] [0.00000000e+000 0.00000000e+000 9.86546146e-312]] [[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]] ‘’’
```python
arr1 = np.eye(3, k = 0)
arr2 = np.eye(3, k = 1)
print(arr1)
print(arr2)
'''
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[[0. 1. 0.]
[0. 0. 1.]
[0. 0. 0.]]
'''
identity()
函数创建n*n单位矩阵,主对角线上元素都为1,其他元素都为0
格式:identity(n, dtype = None)
说明:
- n:单位矩阵的行数(也是列数)
- dtype:指定矩阵元素的数据类型 ```python arr1 = np.identity(3, dtype = int) print(arr1)
‘’’ [[1 0 0] [0 1 0] [0 0 1]] ‘’’
`full()`函数创建由固定值填充的数组<br />格式:`full(shape, fill_vlaue, dtype = None, order = 'C')`<br />说明:
- shape:int或int类型序列,表示矩阵形状
- fill_value:填充值
- dtype:可选参数,指定元素的数据类型
- order:可选参数,取值‘C’或‘F’,表示数组在内存中的存放次序是以行(C)为主还是以列(F)为主,默认值为‘C’。
```python
arr2 = np.full((2, 3), 8)
print(arr2)
'''
[[8 8 8]
[8 8 8]]
'''
3. 使用ndarray()函数创建ndarray数组
常用参数如下表:
参数 | 类型 | 作用 |
---|---|---|
shape | int型tuple | 指定数组的维度和每维的大小 |
dtype | int型、float型等 | 指定数组中元素的类型 |
buffer | ndarray | 用于初始化数组的数组 |
offset | int | buffer中用于初始化数组的首个数据的偏移,是数组元素在内存中所占字节数的整数倍 |
strides | int型tuple | 每个轴的下标增加1时,数据指针在内存中增加的字节数 |
order | ‘C’或者’F’ | ‘C’表示行优先,buffer中的数据按行的顺序存入将要创建的数组中;‘F’表示列优先 |
# buffer中的数据按行的顺序存入将要创建的数组e中
e = np.ndarray(shape = (2, 3), dtype = int,
buffer = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8]),
offset = 0, order = 'C')
# buffer中的数据按列的顺序存入将要创建的数组f中
f = np.ndarray(shape = (2, 3), dtype = int,
buffer = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8]),
offset = 0, order = 'F')
print(e)
print(f)
'''
[[0 1 2]
[3 4 5]]
[[0 2 4]
[1 3 5]]
'''
ndarray对象属性和数据转换
ndarray对象属性及说明表:
ndarray数组对象的属性 | 属性说明 |
---|---|
T | ndarray.T返回数组的转置 |
dtype | 描述数组元素的类型 |
shape | 返回数组的形状,以元组表示的数组的各维的大小 |
ndim | 返回数组的维度 |
size | ndarray.size返回数组中元素的个数 |
itemsize | 返回数组中的单个元素在内存中所占字节数 |
flat | 返回一个数组的迭代器,对flat赋值将导致整个数组的元素被覆盖 |
real/imag | 给出复数数组的实部/虚部 |
nbytes | 返回数组的所有元素所占的存储空间 |
warray = np.array([[1, 2, 3], [4, 5, 6]])
print('维度为:', warray.ndim)
print('形状为:', warray.shape)
print('元素个数为:', warray.size)
'''
维度为: 2
形状为: (2, 3)
元素个数为: 6
'''
warray = np.array([[1, 2, 3], [4, 5, 6]])
warray.shape = (3, 2)
print(warray)
'''
[[1 2]
[3 4]
[5 6]]
'''
arr1 = np.arange(6)
print(arr1.dtype)
arr2 = arr1.astype(np.float64)
print(arr2.dtype)
'''
int32
float64
'''
numpy.random模块
numpy.random模块中常用的随机分布函数表
numpy.random
模块中常用的随机分布函数表:
随机分布函数 | 函数功能 |
---|---|
binomial(n, p, size = None) | 产生size个二项分布的样本值 n表示n次试验,p表示每次试验发生(成功)的概率。 函数的返回值表示n次试验中发生(成功)的次数 |
exponential(scale = 1.0, size = None) | 产生size个指数分布的样本值 这里的scale是β,为标准差,β = 1/λ, λ为单位时间内事件发生的次数 |
normal(loc = 0.0, scale = 1.0, size = None) | 产生size个正态(高斯)分布的样本值 loc为正态分布的均值,scale为正态分布的标准差, size缺省,则采样一个 |
poisson(lam = 1.0, size = None) | 从泊松分布找那个生成随机数 lam是单位时间内事件的平均发生次数 |
uniform(low = 0.0, high = 1.0, size = None) | 产生size个均匀分布[low, high)的样本值 size为int或tuple类型, 如size = (m, n, k),则输出mnk个样本,缺省时输出1个值 |
简单随机数
在NumPy.random模块中,提供了多种随机数的生成函数。randint()
函数:randint函数生成指定范围的随机整数来构成指定形状的数组。
格式:np.random.randint(low, high = None, size = None)
说明:
- 生成size个随机整数,若为元组则指定数组形状
- 取值区间为[low, high)
- 若没有输入参数high,则取值区间为[0, low) ```python arr = np.random.randint(100, 200, size = (2, 4)) print(arr)
‘’’ [[187 187 100 146] [172 114 142 170]] ‘’’
<a name="XatXg"></a>
### 随机分布
`normal()`函数:产生size个正态(高斯)分布的样本值<br />格式:`normal(loc = 0.0, scale = 1.0, size = None)`
```python
from numpy import random
import numpy as np
import matplotlib.pyplot as plt
mu, sigma = 0, 1
# 获取1000个样本值
s = random.normal(loc = mu, scale = sigma, size = 1000)
# 绘制样本的直方图,以及概率密度函数
count, bins, patches = plt.hist(s, 30, density = True)
plt.plot(bins,
1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(- (bins - mu)**2 / (2 * sigma**2)),
linewidth = 2,
color = 'r')
plt.show()
随机排序
numpy.random模块中用于对数组对象随机排序的函数
函数名称 | 函数功能 |
---|---|
shuffle(x) | 打乱对象x(多维数组按照第一维打乱) 直接在原来的数组上进行操作,改变原来数组元素的顺序 无返回值 x可以是数组或者列表 |
permutation(x) | 打乱并返回新对象(多维数组按照第一维打乱) 不直接在原数组上进行操作,而是返回一个新的打乱元素顺序的数组,并不改变原来的数组 x可以是整数或者列表,如果是整数k,那就随机打乱numpy.arange(k) |
import numpy as np
arr1 = np.arange(9).reshape((3, 3))
print('原数组:\n', arr1)
np.random.shuffle(arr1)
print('随机排序后的数组:\n', arr1)
'''
原数组:
[[0 1 2]
[3 4 5]
[6 7 8]]
随机排序后的数组:
[[3 4 5]
[0 1 2]
[6 7 8]]
'''
数组变换
ndarray数组对象提供了一些方法用来改变数组的形状。
改变数组形状的方法 | 功能 |
---|---|
ndarray.reshape(shape, order) | 返回一个具有相同数据域,但shape不一样的视图 |
ndarray.resize(new_shape, orefcheck) | 原地修改数组的形状,需要保持元素个数前后相同 |
ndarray.transpose(*axes) | 返回数组针对某一轴进行转置后的数组,对于二维ndarray,transpose在不指定参数时默认是矩阵转置 |
ndarray.swapaxes(axis1, axis2) | 返回数组axis1轴与axis2轴互换的视图 |
ndarray.flatten(order) | 返回将原数组展平后的一维数组的拷贝(全新的数组) |
ndarray.ravel(order = ‘C’) | 返回将原数组展平后的一维数组的视图 |
1. 数组重塑(reshape函数)
对于定义好的数组,可以通过reshape方法改变其数组维度。
格式:np.reshape(a, newshape, order = 'C')
说明:
- a:需要处理的数据
- newshape:新维度——整数或整数元组 ```python arr1 = np.arange(8) print(‘原数组:\n’, arr1) arr2 = arr1.reshape(4, 2) print(‘重塑后的数组:\n’, arr2)
‘’’ 原数组: [0 1 2 3 4 5 6 7] 重塑后的数组: [[0 1] [2 3] [4 5] [6 7]] ‘’’
reshape的参数中的其中一个可以设置为-1,表示数组的维度可以通过数据本身来推断。
```python
arr1 = np.arange(12)
print('arr1:', arr1)
arr2 = arr1.reshape(2, -1)
print('arr2:\n', arr2)
'''
arr1: [ 0 1 2 3 4 5 6 7 8 9 10 11]
arr2:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
'''
2. 数组重塑(ravel函数和flatten函数)
与reshape相反的方法是数据散开(ravel)或数据扁平化(flatten)。数据重塑不会改变原来的数组。
arr1 = np.arange(12).reshape(3, 4)
arr2 = arr1.ravel()
arr3 = arr1.flatten()
print('arr1:\n', arr1)
print('arr2:', arr2)
print('arr3:', arr3)
'''
arr1:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
arr2: [ 0 1 2 3 4 5 6 7 8 9 10 11]
arr3: [ 0 1 2 3 4 5 6 7 8 9 10 11]
'''
3. 数组合并(hstack函数、vstack函数和concatenate函数)
- hstack函数:实现横向合并
- vstack函数:实现纵向合并
- concatenate函数:可以实现数组的横向或纵向合并,参数axis = 1时进行横向合并,axis = 0时进行纵向合并。 ```python arr1 = np.arange(6).reshape(3,2) arr2 = arr1 * 2 arr3 = np.hstack((arr1, arr2)) arr4 = np.vstack((arr1, arr2)) print(‘arr1:\n’, arr1) print(‘arr2:\n’, arr2) print(‘横向合并hstack为:\n’, arr3) print(‘纵向合并vstack为:\n’, arr4)
‘’’ arr1: [[0 1] [2 3] [4 5]] arr2: [[ 0 2] [ 4 6] [ 8 10]] 横向合并hstack为: [[ 0 1 0 2] [ 2 3 4 6] [ 4 5 8 10]] 纵向合并vstack为: [[ 0 1] [ 2 3] [ 4 5] [ 0 2] [ 4 6] [ 8 10]] ‘’’
<a name="jTHgV"></a>
#### 4. 数组分割(hsplit函数、vsplit函数和split函数)
- hsplit函数:实现数组横向分割
- vsplit函数:实现数组纵向分割
- split函数:实现数组指定方向的分割
```python
arr = np.arange(16).reshape(4, 4)
arr1 = np.hsplit(arr, 2)
arr2 = np.vsplit(arr, 2)
print(arr)
print('横向分割为:\n', arr1)
print('纵向分割为:\n', arr2)
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
横向分割为:
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]), array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
纵向分割为:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
'''
5. 数组转置和轴对称
- transpose方法进行转置
- 直接利用数组的T属性进行数组转置 ```python arr = np.arange(6).reshape(3, 2) arr1 = arr.transpose((1, 0)) arr2 = arr.T print(‘原矩阵:\n’, arr) print(‘函数转置矩阵:\n’, arr1) print(‘属性转置矩阵:\n’,arr2)
‘’’ 原矩阵: [[0 1] [2 3] [4 5]] 函数转置矩阵: [[0 2 4] [1 3 5]] 属性转置矩阵: [[0 2 4] [1 3 5]] ‘’’
<a name="y2SzM"></a>
### 索引和切片
数组索引机制指的是用方括号[]加序号的形式抽取元素、选取数组的某些元素以及为索引处的元素重新赋值。<br />数组的切片操作是用来抽取数组的一部分元素生成新数组。切片是把用冒号“:”隔开的数字置于方括号“[]”里。
> 注意:对Python列表进行切片操作得到的列表是原列表的拷贝,而NumPy对ndarray数组进行切片操作得到的数组是指向相同缓冲区的视图,对所得切片数组元素的改变就是对原数组元素的改变。
<a name="sXYOh"></a>
#### 一维数组的索引和切片
一维数组的索引类似Python中的列表。
```python
arr = np.arange(10)
print(arr)
print(arr[2])
print(arr[-1])
print(arr[1:4])
'''
[0 1 2 3 4 5 6 7 8 9]
2
9
[1 2 3]
'''
数组的切片返回的是原始数组的视图,不会产生新的数据,如果需要的并非视图而是要复制数据,则可以通过copy方法实现。
arr = np.arange(10)
arr1 = arr[-4:-1].copy()
print(arr)
print(arr1)
'''
[0 1 2 3 4 5 6 7 8 9]
[6 7 8]
'''
使用列表索引数组
x = np.arange(10, 1, -1)
print(x)
x[[2, 2, 1, 6]]
'''
[10 9 8 7 6 5 4 3 2]
array([8, 8, 9, 4])
'''
布尔值索引数组
y = np.arange(30)
b = y > 20
y[b]
'''
array([21, 22, 23, 24, 25, 26, 27, 28, 29])
'''
多维数组的索引和切片
对于多维数组,它的每一个维度都有一个索引,各个维度的索引之间用逗号分隔。
也可以使用整数函数和布尔值索引访问多维数组。
arr = np.arange(12).reshape(3, 4)
print(arr)
print('第0行中第1列到第2列的元素:\n', arr[0, 1:3])
print('第2列元素:\n', arr[:, 2])
print('第0行第0列元素:\n', arr[:1, :1])
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
第0行中第1列到第2列的元素:
[1 2]
第2列元素:
[ 2 6 10]
第0行第0列元素:
[[0]]
'''
arr = np.arange(12).reshape(3, 4)
# 从两个序列的对应位置取出两个整数来组成下标:arr[0, 1], arr[1, 3]
print(arr)
print('索引结果1:', arr[(0, 1), (1, 3)])
# 索引第1、2行中第0、2、3列的元素
print('索引结果2:',arr[1:2, (0, 2, 3)])
mask = np.array([1, 0, 1], dtype = np.bool)
# mask是一个布尔数组,它索引第0,2行中第1列元素
print('索引结果3:', arr[mask, 1])
'''
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
索引结果1: [1 7]
索引结果2: [[4 6 7]]
索引结果3: [1 9]
'''
选择数组元素的方法
ndarray.take()
ndarray.take()
函数:根据指定的索引indices从数组对象ndarray中获取对应元素,并构成一个新的数组返回。
格式:ndarray.take(indices[, axis = None, out = None, mode = 'raise'])
说明:
- axis:用来指定选择元素的轴,默认情况下,使用扁平化的输入数组,即把数组当成一个一维数组
- out:是ndarray对象,用来存放函数返回值,要求其shape必须与函数返回值的shape一致
- mode:指定越界索引将如何处理 ```python x = np.array([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]) print(‘第1次取出的元素:\n’, x.take([0, 2, 4])) print(‘第2次取出的元素:\n’, x.take([[2, 5], [3, 6]]))
‘’’ 第1次取出的元素: [0 4 8] 第2次取出的元素: [[ 4 10] [ 6 12]] ‘’’
<a name="TRdXM"></a>
#### ndarray.put()
`ndarray.put()`函数:将数组中索引indices指定的位置处的元素值设置为values中对应的元素值。<br />格式:`ndarray.put(indices, values[, mode])`
```python
x = np.arange(0, 20, 2)
print(x)
# 将x中索引[0, 1]处的值设置为列表[1, 3]中对应的值
x.put([0, 1], [1, 3])
print(x)
'''
[ 0 2 4 6 8 10 12 14 16 18]
[ 1 3 4 6 8 10 12 14 16 18]
'''
ndarray.sezrchsorted()
ndarray.searchsorted()
函数:将v插入到当前有序的数组中,返回插入的位置索引。
格式:ndarray.searchsorted(v, side = 'left', sorter = None)
w = np.array([1, 2, 3, 3, 3, 3, 6, 7, 9, 10, 12])
w.searchsorted(3)
print(w.searchsorted(3))
print(w.searchsorted(3, side = 'right'))
'''
2
6
'''
ndarray.itemset()
ndarray.itemset()
函数:修改数组中某个元素的值
歌手ndarray.itemset(*args)
a = np.array([[0, 1, 2], [33, 4, 5], [6, 7, 8]])
print('修改前:\n', a)
a.itemset((1, 2), 12)
print('修改后:\n', a)
'''
修改前:
[[ 0 1 2]
[33 4 5]
[ 6 7 8]]
修改后:
[[ 0 1 2]
[33 4 12]
[ 6 7 8]]
'''
NumPy多维数组的运算
ufunc函数
ufunc函数全称为通用函数,是一种能够对数组中的所有元素进行操作的函数。
对一个数组进行重复运算时,使用ufunc函数比使用math库中的函数效率要高很多。
常用的ufunc函数运算
四则运算
加(+)、减(-)、乘()、除(/)、幂(*)。
数组减的四则运算表示对每个数组中的元素分别进行四则运算,所以形状必须相同。
比较运算
、<、==、>=、<=、!=。
比较运算返回的结果是一个布尔数组,每个元素为每个数组对应元素的比较结果。算术运算的二元函数
numpy模块中对两个数组的元素进行算术运算的二元函数。
函数 | 说明 |
---|---|
add(a, b) | 将两个数组中对应的元素相加,a、b为两个ndarray数组 |
subtract(a, b) | 将两个数组中对应的元素相减 |
multiply(a, b) | 将两个数组中对应的元素相乘 |
power(a, b) | 对第一个数组中的元素x,第二个数组中的对应位置的元素y,计算x的y次方 |
greate、greate_equal、 less、less_equal、 equal、not_equal |
将两个数组中对应的元素进行比较运算,最终产生布尔型的数组。 相当于运算符>、>=、<、<=、==、!= |
数组最常用的运算是算术运算,可以为数组的每个元素加上或乘以某个数值,可以让两个数组对应元素之间做加、减、乘、除运算等。
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
print('a = \n', a)
print('a + 6 = \n', a + 6)
'''
a =
[[1 2 3]
[4 5 6]]
a + 6 =
[[ 7 8 9]
[10 11 12]]
'''
通过在数组和数字之间使用条件运算符,比如大于号,将会得到由布尔值组成的数组,对于原数组中满足条件的元素,布尔数组中处于同等位置的元素为True。
import numpy as np
a = np.array([[0.51691317, 0.20933602, 0.22460165],
[0.91598144, 0.43223077, 0.59339314]])
b = a[a > 0.5]
print('a > 0.5?\n', a > 0.5)
print('a > 0.5:\n', b)
'''
a > 0.5?
[[ True False False]
[ True False True]]
a > 0.5:
[0.51691317 0.91598144 0.59339314]
'''
逻辑运算
np.any
函数表示逻辑“or”np.all
函数表示逻辑“and”- 运算结果返回布尔值 ```python a = np.array([1, -1, 5]) b = np.array([4, 0, 3]) c = np.any([a, b]) print(‘a = ‘, a) print(‘b = ‘, b) print(‘any(a, b) = ‘, c)
‘’’ a = [ 1 -1 5] b = [4 0 3] any(a, b) = True ‘’’
<a name="s8aVq"></a>
### 条件逻辑运算
在NumPy中可以利用基本的逻辑运算就可以实现数组的条件运算。
```python
arr1 = np.array([1, 3, 5, 7])
arr2 = np.array([2, 4, 6, 8])
cond = np.array([True, False, True, False])
result = [(x if c else y) for x, y, c in zip(arr1, arr2, cond)]
result
'''
[1, 4, 5, 8]
'''
这种方法对大规模数组处理效率不高,也无法用于多维数组。
NumPy提供的where方法可以克服这些问题。np.where()
函数:满足条件(condition)输出x,不满足输出y
格式:np.where(condition, x, y)
np.where([[True, False], [True, True]], [[1, 2], [3, 4]], [[9, 8], [7, 6]])
'''
array([[1, 8],
[3, 4]])
'''
np.where()
中若只有条件(condition),没有x和y,则输出满足条件元素的坐标。
这里的坐标以tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。
w = np.array([2, 5, 6, 3, 10])
np.where(w > 4)
'''
(array([1, 2, 4], dtype=int64),)
'''
ufunc函数的广播机制
广播(broadcasting)是指不同形状的数组之间执行算术运算的方式。
需要遵循4个原则:
- 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在左边加1补齐。
- 如果两个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度为1的维度进行扩展,以匹配另一个数组的形状。
- 输出数组的shape是输入数组shape的各个轴上最大值
- 如果两个数组的形状在任何一个维度上都不匹配,并且没有任何一个维度等于1,则引发异常。 ```python arr1 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2]]) arr2 = np.array([1, 2, 3]) print(‘arr1:\n’, arr1) print(‘arr2:\n’, arr2) print(‘arr1 + arr2:\n’, arr1 + arr2)
‘’’ arr1: [[0 0 0] [1 1 1] [2 2 2]] arr2: [1 2 3] arr1 + arr2: [[1 2 3] [2 3 4] [3 4 5]] ‘’’
<a name="dQMrN"></a>
### 常用统计函数
Numpy中提供了很多用于统计分析的函数,常见的有sum、mean、std、var、min和max等。<br />ndarray数组对象的很多统计计算方法都有一个axis参数,它有如下作用:
- 当axis = None(默认)时,数组被当成一个一维数组,对数组的计算操作是对整个数组进行的,比如sum方法,就是求数组中所有元素的和
- 当axis被指定一个int整数时,对数组的计算操作是以提供的axis轴进行的,axis = 0表示对column(列)进行操作,axis = 1表示对row(行)进行操作
| ndarray数组对象的常用统计计算方法 | 功能 |
| --- | --- |
| ndarray.max(axis = None, out = None) | 返回根据指定的axis计算最大值,axis = 0表示求各column的最大值,axis = 1表示求各row的最大值 |
| ndarray.argmax(axis = None, out) | 返回根据指定axis计算最大值索引,out是ndarray对象,用来存放函数返回值,要求其shape必须与函数返回值的shape一致 |
| ndarray.min(axis = None, out None) | 返回根据指定的axis计算最小值 |
| ndarray.argmin(axis = None, out = None) | 返回指定axis最小元素的索引 |
| ndarray.ptp(axis, out) | 返回根据指定axis计算最大值与最小值的差 |
| ndarray.clip(min, max, out) | 返回数组元素限制在[min, max]之间的新数组,小于min的转为min,大于max的转为max |
| ndarray.trace(offset = 0,axis1 = 0, aixs2 = 1, dtype = None, out = None) | 返回数组的迹(对角线元素的和),offset表示离开主对角线的偏移量 |
| ndarray.sum(axis = None, dtype = None, out = None) | 返回指定axis的所有元素的和,默认求所有元素的和 |
| ndarray.cumsum(axis = None, dtype = None, out = None) | 按照所给定的轴参数返回元素的累计和 |
| ndarray.mean(axis = None, dtype = None, out = None) | 返回指定axis的数组元素均值 |
| ndarray.var(axis = None, dtype = None, out = None, ddof = 0) | 根据指定的axis计算数组的方差 |
| ndarray.std(axis = None, dtype = None, out = None, ddof = 0) | 根据指定axis计算数组的标准差 |
| ndarray.prod(axis = None, dtype = None, out = None) | 返回指定轴的所有元素乘积 |
| ndarray.cumprod(axis = None, dtype = None, out = None) | 返回指定轴的累积 |
<a name="axpe6"></a>
### 统计计算
`ndarray.max()`函数:返回根据指定的axis计算最大值<br />格式:`ndarray.max(axis=None, out=None)`<br />说明:
- axis=0表示求各column的最大值,axis=1表示求各row的最大值
- out是ndarray对象,用来存放函数返回值,要求其shape必须与函数返回值的shape一致
```python
import numpy as np
a = np.array([[2, 3, 4, 9], [8, 7, 6, 5], [4, 3, 5, 8]])
o = np.ndarray(shape = 3)
# axis = 1表示求各row的最大值
a.max(axis = 1, out = o)
print(o)
'''
[9. 8. 8.]
'''
ndarray.clip()
函数:返回数组元素限制在[min, max]之间的新数组(小于min的转为min,大于max的转为max)。
格式:ndarray.clip(min, max, out)
import numpy as np
a = np.array([[2, 3, 4, 9], [8, 7, 6, 5], [4, 3, 5, 8]])
print(a.clip(5, 8))
'''
[[5 5 5 8]
[8 7 6 5]
[5 5 5 8]]
'''
ndarray.cumsum()
函数:按照给定轴参数返回元素的累计和。
格式:ndarry.cumsum(axis = None, dtype = None, out = None)
import numpy as np
a = np.array([[2, 3, 4, 9], [8, 7, 6, 5], [4, 3, 5, 8]])
print('a = \n', a)
# 按行求累计和
print('按行求累计和=\n', a.cumsum(axis = 1))
'''
a =
[[2 3 4 9]
[8 7 6 5]
[4 3 5 8]]
按行求累计和=
[[ 2 5 9 18]
[ 8 15 21 26]
[ 4 7 12 20]]
'''
重复数据与去重
统计分析中有时也需要把一个数据重复若干次,使用tile和repeat函数即可实现此功能。tile()
函数:把一个数组数据重复
格式:np.tile(A, reps)
说明:
- A:要重复的数组
- reps:重复次数
repeat()
函数:把一个数组数据重复
格式:np.repeat(A, reps, axis = None)
说明:
- A:需要重复的数组元素
- reps:重复次数
- axis:指定沿哪个轴进行重复,axis = 0表示按行进行元素重复;axis = 1表示按列进行元素重复 ```python import numpy as np arr = np.arange(5) print(‘原数组:’, arr) wy = np.tile(arr,3) print(‘重复数据1:’, wy) arr2 = np.array([[1, 2, 3], [4, 5, 6]]) print(‘重复数据2:\n’, arr2.repeat(2, axis = 0))
‘’’ 原数组: [0 1 2 3 4] 重复数据1: [0 1 2 3 4 0 1 2 3 4 0 1 2 3 4] 重复数据2: [[1 2 3] [1 2 3] [4 5 6] [4 5 6]] ‘’’
`unique()`函数:去除一维数组或列表中重复的元素,并按元素大小由小到大返回一个新的元组或者列表。<br />格式:`np.unique(A)`
```python
import numpy as np
names = np.array(['红色', '蓝色', '黄色', '白色', '红色'])
print('原数组:', names)
print('去重后的数据:', np.unique(names))
'''
原数组: ['红色' '蓝色' '黄色' '白色' '红色']
去重后的数据: ['白色' '红色' '蓝色' '黄色']
'''
排序
ndarray数组对象的排序元素常用方法如表所示。
排序元素的方法 | 方法功能 |
---|---|
ndarray.sort(axis = -1, kind = ‘quicksort’, order = None) |
- 原地对数组元素进行排序,即排序后改变了原数组,无返回值 - axis指定排序沿着数组的轴方向,0表示按行,1表示按列,axis默认值为-1,表示沿最后的轴排序 - kind指定排序的算法,其取值集合为{‘quicksort’, ‘mergesort’, ‘heapsort’} - order指定元素的排列顺序,默认升序 |
ndarray.argsort(axis = -1, kind = ‘quicksort’, order = None) |
返回对数组进行升序排序之后的数组元素在原数组中的索引 |
import numpy as np
y1 = np.array([[0, 15, 10, 5], [25, 22, 3, 2], [55, 45, 59, 50]])
print('原y1=\n', y1)
y1.sort()
print('排序后的y1=\n', y1)
'''
原y1=
[[ 0 15 10 5]
[25 22 3 2]
[55 45 59 50]]
排序后的y1=
[[ 0 5 10 15]
[ 2 3 22 25]
[45 50 55 59]]
'''
np.argsort函数和np.lexsort函数根据一个或多个键值对数据集进行排序。np.argsort()
:返回数组值从大到小的索引值np.lexsort()
:返回按照最后一个传入数据排序的结果
使用argsort和lexsort函数,可以在给定一个或多个键时,得到一个由整数构成的索引数组,索引值表示数据在新的序列中的位置。
import numpy as np
arr = np.array([7, 9, 5, 2, 9, 4, 3, 1, 4, 3])
print('原数组:', arr)
print('排序后:', arr.argsort())
'''
原数组: [7 9 5 2 9 4 3 1 4 3]
排序后: [7 3 6 9 5 8 2 0 1 4]
'''
import numpy as np
a = np.array([7, 2, 1, 4])
b = np.array([5, 2, 6, 7])
c = np.array([5, 2, 4, 6])
d = np.lexsort((a, b, c))
print('排序后:', list(zip(a[d], b[d], c[d])))
'''
排序后: [(2, 2, 2), (1, 6, 4), (7, 5, 5), (4, 7, 6)]
'''
数组拼接与切分
垂直拼接
vstack()
函数:用来将列数相同的数组序列tup中的数组进行竖直方向的拼接,即把数组序列tup中后一个数组作为行追加到前一个数组的下边,数组向竖直方向上生长。
格式:np.vstack(tup)
说明:
- 参数tup的类型可以是元组、列表或numpy数组
- 返回结果为numpy数组 ```python import numpy as np a = np.array([1, 2, 3]) b = np.array([2, 3, 4]) print(np.vstack((a, b)))
‘’’ [[1 2 3] [2 3 4]] ‘’’
<a name="MzVtg"></a>
#### 水平拼接
`hstack()`函数:用来将行数相同的数组序列tup中的数组进行水平方向的拼接,即把数组序列tup中后一个数组作为列追加到前一个数组的右边,数组向水平方向上生长。<br />格式:`np.hstack(tup)`<br />说明:
- 参数tup的类型可以是元组、列表或numpy数组
- 返回结果为numpy数组
```python
a = np.array([1, 2, 3]).reshape(3, 1)
b = np.array([4, 5, 6]).reshape(3, 1)
c = np.hstack((a, b))
print('a=\n', a)
print('b=\n', b)
print('c=\n', c)
'''
a=
[[1]
[2]
[3]]
b=
[[4]
[5]
[6]]
c=
[[1 4]
[2 5]
[3 6]]
'''
水平切分
hsplit()
函数:用来水平方向上切分数组
格式:np.hsplit(ary, indices_or_sections)
说明:
- ary:表示待切分的数组
- indices_or_sections:可以是一个整数,表示平均切分的个数,必须要均等分,否则会报错,也可以是一个数组元素递增的整数一维数组,如:[2, 3]表示要将ary分成ary[:2]、ary[2:3]、ary[3:]三个子数组。 ```python a = np.arange(16).reshape(4, 4) x, y, z = np.hsplit(a, [2, 3]) print(‘a:\n’, a) print(‘x:\n’, x) print(‘y:\n’, y) print(‘z:\n’, z)
‘’’ a: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] x: [[ 0 1] [ 4 5] [ 8 9] [12 13]] y: [[ 2] [ 6] [10] [14]] z: [[ 3] [ 7] [11] [15]] ‘’’
<a name="Ewhgl"></a>
#### 竖直切分
`vsplit()`函数:用来竖直方向上切分数组<br />格式:np.vsplit(ary, indices_or_sections)
```python
a = np.arange(16).reshape(4, 4)
x, y = np.vsplit(a, 2)
print('a:\n', a)
print('x:\n', x)
print('y:\n', y)
'''
a:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
x:
[[0 1 2 3]
[4 5 6 7]]
y:
[[ 8 9 10 11]
[12 13 14 15]]
'''
线性代数运算
在NumPy中,用“*”进行两个数组相乘是两个数组对应位置上的元素相乘。
NumPy用dot()函数执行一般意义上的矩阵(用ndarray数组表示)乘积。
A = np.arange(1, 10).reshape((3, 3))
B = np.ones(shape = (3, 3), dtype = int)
print('A=', A)
print('B=', B)
C = np.dot(A, B)
D = A.dot(B)
E = A * B
print('dot(A, B)=', C)
print('A.dot(B)=', D)
print('A*B=', E)
'''
A= [[1 2 3]
[4 5 6]
[7 8 9]]
B= [[1 1 1]
[1 1 1]
[1 1 1]]
dot(A, B)= [[ 6 6 6]
[15 15 15]
[24 24 24]]
A.dot(B)= [[ 6 6 6]
[15 15 15]
[24 24 24]]
A*B= [[1 2 3]
[4 5 6]
[7 8 9]]
'''
线性代数运算常用函数
numpy的linalg模块提供了一些进行线性代数运算的函数。
函数 | 描述 |
---|---|
det | 计算矩阵行列式 |
eig(A) | 计算方阵A的特征值和特征向量 |
inv(A) | 计算方阵A的逆 |
svd(A, full_matrices = 1, compute_uv = 1) |
对矩阵进行奇异值分解 该函数返回3个矩阵-U、Sigma和V 其中U和V是正交矩阵,Sigma是输入矩阵的奇异值 |
solve(a, b) | 求解形如AX=B的线性方程组 其中A是一个N*N的二维数组,而B是一个长度为N的一维数组,数组X是待求解的线性方程组的解 |
创建numpy矩阵
创建矩阵有两种方法:
- mat()函数
- matrix()函数 ```python matr1 = np.mat(‘1, 2, 3, 4, 5, 6, 7, 8, 9’, dtype = np.float64) matr2 = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(matr1) print(matr2)
‘’’ [[1. 2. 3. 4. 5. 6. 7. 8. 9.]] [[1 2 3] [4 5 6] [7 8 9]] ‘’’
<a name="MNlJF"></a>
### 矩阵运算
矩阵运算是针对整个矩阵中的每个元素进行的,和使用循环比,在运算速度上更快。<br />矩阵和矩阵之间可以进行+、-、*、/,其中*为点乘,需要特别注意。如果要对应元素相乘使用multipy()函数。
<a name="OkDAT"></a>
### 矩阵特有的属性
| 属性 | 含义 |
| --- | --- |
| T | 返回矩阵的转置 |
| H | 返回矩阵的共轭转置 |
| I | 返回逆矩阵 |
| A | 返回矩阵的视图 |
<a name="tcKtR"></a>
# 读写数据文件
<a name="U85B5"></a>
## 读写二进制文件
numpy中的`save()`函数以二进制格式保存数组到一个文件中,文件的扩展名为“.npy”,该扩展名是由系统自动添加的。<br />numpy中的`load()`函数从二进制文件中读取数据。<br />格式:`numpy.save(file, arr)`<br />说明:
- file:用来保存数组的文件名或文件路径,是字符串类型
- arr:要保存的数组
```python
import numpy as np
A = np.arange(16).reshape(2, 8)
print(A)
np.save('C:/test/A.npy', A)
np.load('C:/test/A.npy')
读写文本文件
np.savetxt()
函数:用于将数组中的数据存放到文本文件中
格式:np.savetxt(filename, arr, fmt = '%.18e', delimiter = '', newline = '\n')
说明:
- filename:存放数据的文件名
- arr:要保存的数组
- fmt:指定数据存入格式
- delimiter:数据列之间的分隔符,数据类型为字符串,默认值为’ ‘
- newline:数据行之间的分隔符
np.loadtxt()
函数:读取文本文件
格式:np.loadtxt(fname, dtype = , comments = '#', delimiter = None, converters = None, skiprows = 0,usecol = None, unpack = False, ndmin = 0, encoding = 'bytes')
说明:
- fname:str,读取的CSV文件名
- delimiter:str,数据的分隔符
- usecols:tuple,执行加载数据文件中的哪些列
- unpack:bool,是否将加载的数据拆分为多个组,True表示拆,False表示不拆
- skipprows:int,跳过多少行,一般用于跳过前几行的描述性文字
- encoding:bytes,编码格式
import numpy as np
b = np.arange(10).reshape(2, 5)
print(b)
np.savetxt('C:/test/b.txt', b)
print(np.loadtxt('C:/b.txt'))
# 将数组元素保存为浮点数,以逗号分隔
np.savetxt('C:/test/c.txt', b, fmt = '%f', delimiter = ',')
# load时叶鏊指定以逗号分隔,指定要读取的数据类型为浮点型
np.loadtxt('C:/test/c.txt', dtype = 'f', delimiter = ',')