Python的NumPy库(一)基础用法
NumPy库并不是Python的标准库,但其在机器学习、大数据等很多领域有非常广泛的应用,NumPy本身就有比较多的内容,全部的学习可能涉及许多的内容,但我们在这里仅学习常见的使用,这些内容对于我们日常使用NumPy是足够的。
NumPy简介
NumPy是Python中科学计算的基础包,它代表 “Numeric Python”。Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarray ,它拥有一些额外的功能。 2005年,Travis Oliphant 通过将 Numarray 的功能集成到 Numeric 包中来创建 NumPy 包。
NumPy的核心是多维数组(ndarray),以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。
NumPy数组 和 原生Python Array(数组)之间有几个重要的区别:
- NumPy 数组在创建时具有固定的大小,与Python的原生数组对象(可以动态增长)不同。更改ndarray的大小将创建一个新数组并删除原来的数组。
- NumPy 数组中的元素都需要具有相同的数据类型,因此在内存中的大小相同。 例外情况:Python的原生数组里包含了NumPy的对象的时候,这种情况下就允许不同大小元素的数组。
- NumPy 数组有助于对大量数据进行高级数学和其他类型的操作。通常,这些操作的执行效率更高,比使用Python原生数组的代码更少。
- 越来越多的基于Python的科学和数学软件包使用NumPy数组; 虽然这些工具通常都支持Python的原生数组作为参数,但它们在处理之前会还是会将输入的数组转换为NumPy的数组,而且也通常输出为NumPy数组。换句话说,为了高效地使用当今科学/数学基于Python的工具(大部分的科学计算工具),你只知道如何使用Python的原生数组类型是不够的 - 还需要知道如何使用 NumPy 数组。
NumPy数组主要是用来解决数学问题,包括功能(矩阵计算)和性能两个方面,并且性能更为关键。
NumPy数组主要是用来解决数学问题的,所以需要学习者具备一定的数学知识,比如矩阵、线性代数等等,本文假定学习者已经掌握了这些数学基础知识。
NumPy多维数组定义
NumPy多维数组有多种定义方法,我们主要学习常见的几种。
对象构造方法
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
返回NumPy数组。
参数说明:
object:初始化的数组值,可以是Python数组,也可以是序列类型的对象,如果是一个嵌套的序列对象,就会生成一个多维数组
。dtype:
数组元素的数据类型。copy
:对象是否被复制。order
:排序方式,C
(按行)、F
(按列)或A
(任意,默认)。subok:
默认情况下,返回的数组被强制为基类数组。 如果为true
,则返回子类。ndmin
:指定返回数组的最小维数。
数组对象的属性
NumPy 数组的维数称为秩(rank),秩就是轴(axis)的数量,可以相像为坐标轴,一维数组就是一维坐标轴,二维数组就是二维坐标轴,依次类推。
axis=0,表示第1条轴,一般我们称之为横轴,实际是沿着横轴对每一列进行操作。
axis=1,表示第2条轴,一般我们称之为纵轴,实际是沿着纵轴对每一行进行操作。
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的形状,就是各维度的元素数的列表,例如举证就是(n,m),维度数相同但形状并不一定相同,例如矩阵都是二位的,但(3,3)的矩阵和(4,3)的矩阵形状是不同的 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
注意:初学者很容易将维度和形状搞混淆,维度是坐标轴的概念,一维就是一条直线,二维就是十字交叉的坐标轴,三维就是立方体一样的三轴坐标。 形状是比维度之下的长度的描述,描述的是各维度的长度,如一维的形状就是描述一条线段的长度(5个元素长度就是5,100个元素长度就是100),二维的形状就是描述长方形的两条边的长度,长是横轴,宽是纵轴,用二元元组描述横轴和纵轴,三维的形状就是描述长方体的三条边的长度,长、宽、高的三元组。同样是二维数组,会因为形状不同而不同,如长宽是(3,2)的数组和长宽为(2,3)是完全不同的两个数组。
几个维度在numpy是通过嵌套几层中括号来表示的,形状是通过中括号里的元素个数来表示的(中括号里的每一个中括号也是一个元素)。
a = np.array([[1,2,3,4], [10,20+5j,30+1j,40+2j]])
print(a)
print(a.ndim) #2
print(a.shape) #(2, 4)
print(a.dtype) #int64
print(a.itemsize) #8
print(a.flags)
# C_CONTIGUOUS: True
# F_CONTIGUOUS: False
# OWNDATA: True
# WRITEABLE: True
# ALIGNED: True
# WRITEBACKIFCOPY: False
print(a.real)
#[[ 1. 2. 3. 4.]
# [10. 20. 30. 40.]]
print(a.imag)
#[[0. 0. 0. 0.]
# [0. 5. 1. 2.]]
print(a.data)
#<memory at 0x108540040>
基于序列类型创建数组
可以基于序列类型生成数组,元素的类型并不限定为数值型,最终元素的类型会被转换为dtype:
import numpy as npa = np.array([1,2,3,4])
print(a) #[1 2 3 4]b = np.array(['a','b','c', 'd'])
print(b) #['a' 'b' 'c' 'd']c = np.array(['abc', 'def'])
print(c) #['abc' 'def']
如果元素的类型不一致会ValueError的异常:
a = np.array([1,2,3,4, [1,2]])
print(a)
#ValueError: setting an array element with a sequence.
但注意:python会根据输入的数据类型的兼容性,进行自我适应,调整最终的dtype对象:
import numpy as npa = np.array([1,2,3,4,2])
print(a) #[1 2 3 4 2]
print(a.dtype) #int64
a = np.array([1,2,3,4,2.0])
print(a) #[1. 2. 3. 4. 2.]
print(a.dtype) #float64
a = np.array([1,2,3,4,'ab'])
print(a.dtype) #<U21
print(a) #['1' '2' '3' '4' 'ab']
元素也可以支持字典:
s = np.array([{1:'1'}, {2:'2', 3:'3'}])
print(s) #[{1: '1'} {2: '2', 3: '3’}]
print(s.dtype) #object
元素也支持自定义对象
class MyClass:def __init__(self, a, b):self.a = aself.b = bdef __repr__(self):return f'(MyClass {self.a=}, {self.b=})'def foo(self):passc = np.array([MyClass(1, 2), MyClass('s', 'c')])
print(c) #[(MyClass self.a=1, self.b=2) (MyClass self.a='s', self.b='c')]
print(c.dtype) #object
字典和自定义类都被识别为object类型,所以它们也可以被放在一起:
c = np.array([MyClass(1, 2), MyClass('s', 'c'), MyClass2(), {2:'2', 3:'3'}])
print(c) #[(MyClass self.a=1, self.b=2) (MyClass self.a='s', self.b='c') <__main__.MyClass2 object at 0x1094ae050> {2: '2', 3: '3'}]
print(c.dtype) #object
如果要生成多维数组,需要列表对象是嵌套对象:
import numpy as npa = np.array([[1,2,3,4], [10,20,30,40]])
print(a)
'''
[[ 1 2 3 4][10 20 30 40]]'''
如果直接使用元组作为元素,NumPy会把它识别为多维数组:
a = np.array([(1,2,3,4), (10,20,30,40)])
print(a)
‘’’
[[ 1 2 3 4][10 20 30 40]]
’‘’
也可以通过指定ndmin来指定最小维数
b = np.array(('a', 'b', 'c'), ndmin=2)
print(b)
#[['a' 'b' 'c']]
通过dtype指定数组元素的类型:
c = np.array((20,30,40,50), ndmin=2, dtype=complex)
print(c)
#[[20.+0.j 30.+0.j 40.+0.j 50.+0.j]]
dtype支持的数值类型
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型:
类型 | 代码 | 说明 |
---|---|---|
bool_ | b | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) | |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 | |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) | |
int8、uint8 | i1、u1 | 有符号位和无符号位的8bit整数,相当于一个字节 |
int16、uint16 | i2、u2 | 有符号位和无符号位的16bit整数,2字节整数 |
int32、uint32 | i4、u4 | 有符号位和无符号位的32bit整数,4字节整数 |
int64、uint64 | i8、u8 | 有符号位和无符号位的64bit整数,8字节整数 |
float_ | float64 类型的简写 | |
float16 | f2 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | f4 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | f8 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 | |
complex64 | c8 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | c16 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
bytes | S | C格式的字符串 |
Unicode | U | Unicode格式的字符串 |
数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面::
- 数据的类型(整数,浮点数或者 Python 对象)
- 数据的大小(例如, 整数使用多少个字节存储)
- 数据的字节顺序(小端法或大端法),通过对数据类型预先设定 < 或 > 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
- 在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
- 如果数据类型是子数组,那么它的形状和数据类型是什么。
numpy.dtype(object, align, copy)
返回NumPy的数据类型
参数说明:
- object - 要转换为的数据类型对象
- align - 如果为 true,填充字段使其类似 C 的结构体。
- copy - 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用
dt = np.dtype(np.int32)
print(dt)
#int32dt = np.dtype('i4')
print(dt)
#int32dt = np.dtype('<i4')
print(dt)
#int32
将数据类型应用于 ndarray 对象:
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a)
#[(10,) (20,) (30,)]
下面的示例定义一个结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象。
STUDENT = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(STUDENT)
#[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
a = np.array([('John', 12, 91.5),('Rose', 13, 99)], dtype = STUDENT)
print(a)
#[(b'John', 12, 91.5) (b'Rose', 13, 99. )]
print(a.dtype)
#[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')]
从上面的例子可以看出,dtype定义的结构并没有被识别为object,而是一种带描述的结构体。
软拷贝数组
numpy.asarray(a, dtype = None, order = None)
numpy.asarray 类似 numpy.array,基于存在的对象a(必须是数组,或序列等)创建一个新的数组对象。
array()和asarray()方法都能将序列对象转换为NumPy数组,二者:
- 当他们的参数是列表型数据(list)时,二者没有区别;
- 当他们的参数是数组类型(array)时,np.array()会返回参数数组的一个副本(copy,两者值一样但指向不同的内存),np.asarray()会返回参数数组的一个视图(两者指向同一块内存).
- np.array()的副本会新开辟一块内存,对于大数组来说,会存在大量的复制操作,速度更慢且需要耗费大量内存;
- np.asarray()的视图相当于新增加了一个指向当前内存的引用,不存在复制操作,速度更快且节约内存。注意通过其中的一个引用修改数据,其他引用的数据也会跟着变,因为他们指向同一块内存区域。
a1 = np.asarray([[1, 2, 3], [4, 5, 6]])
print(f'{a1=}')
b1 = np.asarray(a1)
print(f'{b1=}')
b2 = np.array(a1)
print(f'{b2=}')
a1[1][1] = 10
print('-------')
print(f'{a1=}')
print(f'{b1=}')
print(f'{b2=}’)‘’'
a1=array([[1, 2, 3],[4, 5, 6]])
b1=array([[1, 2, 3],[4, 5, 6]])
b2=array([[1, 2, 3],[4, 5, 6]])
-------
a1=array([[ 1, 2, 3],[ 4, 10, 6]])
b1=array([[ 1, 2, 3],[ 4, 10, 6]])
b2=array([[1, 2, 3],[4, 5, 6]])
‘''
创建空数组
numpy.empty(shape, dtype = float, order = 'C')
创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组。
参数说明:
- shape:数组的形状元组,例如矩阵表示为(n,m),就是n 行 m 列;
- dtype:元素的类型,默认是浮点数;
- order:数组在内存中的存储顺序,'C' 是C 的行数组,或者 'F'是 FORTRAN 的列数组。
x = np.empty((3,2), dtype=int)
print(x)
‘’'
[[ 0 2043][ 1 0][ 0 0]]
‘''
注意 − 数组元素为随机值,因为它们未初始化。
创建0填充数组
numpy.zeros(shape, dtype = float, order = 'C')
创建指定维度的数组,数组元素以 0 来填充
参数说明:
- shape:数组的形状;
- dtype:元素的类型,默认是浮点数;
- order:数组在内存中的存储顺序,'C' 是C 的行数组,或者 'F'是 FORTRAN 的列数组。
x = np.zeros((3,2), dtype=int)
print(x)
y = np.zeros((2,3), dtype=[('NAME', 'S20'), ('AGE', 'i2')])
print(y)‘’'
[[0 0][0 0][0 0]]
[[(b'', 0) (b'', 0) (b'', 0)][(b'', 0) (b'', 0) (b'', 0)]]
‘''
创建1填充数组
numpy.ones(shape, dtype = None, order = 'C')
创建指定维度的形状,数组元素以 1 来填充,与0填充一样,只是换成用1来填充。
创建n填充数组
np.full(shape, fill_value, dtype=None, order='C')
创建指定维度的形状,数组元素以 fill_value来填充,与0填充一样,只是换成用1来填充。
x = np.full((3,2), 'OK')
print(x)
’’’
[['OK' 'OK']['OK' 'OK']['OK' 'OK’]]
‘’‘
仿制0填充数组
numpy.zeros_like(a, dtype=None, order='K', subok=True, shape=None)
用于创建一个与给定数组具有相同形状的数组,数组元素以 0 来填充。
参数说明:
- a:要仿制的数组
- dtype:元素的类型,默认是浮点数;
- order:数组在内存中的存储顺序,可选值为 'C'(按行优先)或 'F'(按列优先),默认为 'K'(保留输入数组的存储顺序);
- subok:是否允许返回子类,如果为 True,则返回一个子类对象,否则返回一个与 a 数组具有相同数据类型和存储顺序的数组;
- shape:创建的数组的形状,如果不指定,则默认为 a 数组的形状。
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
za = np.zeros_like(a)
print(za)
‘’'
[[0 0 0][0 0 0][0 0 0]]
‘''
仿制1填充数组
numpy.ones_like(a, dtype=None, order='K', subok=True, shape=None)
创建一个与给定数组具有相同形状的数组,与仿制0填充数据一样,只是数组元素以 1 来填充。
仿制n填充数组
numpy.full_like(a, fill_value,dtype=None, order='K', subok=True, shape=None)
创建一个与给定数组具有相同形状的数组,与仿制0填充数据一样,只是数组元素以 fill_value 来填充。
从流创建数组
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
注意:buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
参数说明:
- buffer:任意流对象
- dtype:数组的元素类型
- count:读取的数据数量,默认为-1,读取所有数据。
- offset:流的偏移量,默认为0
bs = b'This is a test case!'
a = np.frombuffer(bs, dtype='S2')
print(a)
#[b'Th' b'is' b' i' b's ' b'a ' b'te' b'st' b' c' b'as' b'e!']
从迭代器创建数组
numpy.fromiter(iterable, dtype, count=-1)
可迭代对象中建立 ndarray 对象,返回一维数组。
参数说明:
- iterable:待提供数据的迭代器
- dtype:数组的元素类型
- count:读取的数据数量,默认为-1,读取所有数据。
it = iter(range(5))
x = np.fromiter(it, dtype=int)
print(x) #[0 1 2 3 4]
创建范围数组
类似于Python的range:
numpy.arange(start, stop, step, dtype)
参数说明:
- start:起始值,创建的数组包含这个数(闭区间)
- stop:终止值,创建的数组将不包含这个数(开区间)
- step:步长,默认是1
- dtype:数组的元素类型,如果没有提供,则会使用输入数据的类型。
import numpy as npx = np.arange(5)
print (x) #[0 1 2 3 4]
构建等差数列数组
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
创建一个一维数组,数组的元素是一个等差数列。
参数说明:
- start:起始值,创建的数组包含这个数(闭区间)
- end:终止值,如果
endpoint
为true
,该值包含于数列中 - num:要生成的等步长的样本数量,默认为
50
- endpoint:该值为
true
时,数列中包含stop
值,反之不包含,默认是True。 - retstep:如果为 True 时,生成的数组中会显示间距,反之不显示。
- dtype:数组的元素类型
numpy.linspace是numpy.arange的增强版本。
a = np.linspace(10, 15, num=6, dtype=float)
print(a) #[10. 11. 12. 13. 14. 15.]
a = np.linspace(10, 20, num=6, dtype=float)
print(a) #[10. 12. 14. 16. 18. 20.]
a = np.linspace(10, 20, num=6, endpoint=False, dtype=float)
print(a) #[10. 11.66666667 13.33333333 15. 16.66666667 18.33333333]
#10, 10+1+2/3, 10+(1+2/3)*2, 10+(1+2/3)*3, 10+(1+2/3)*4, 10+(1+2/3)*5, 10+(1+2/3)*6=20
a = np.linspace(10, 19, num=6, endpoint=False, dtype=float)
print(a) #[10. 11.5 13. 14.5 16. 17.5]
如果endpoin=Fasle,实际是把num计算为num+1,然后取前面的num位。
构建等比数列数组
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
创建一个于等比数列数组。
参数说明:
- start:起始值,创建的数组包含这个数(闭区间)
- end:终止值,如果
endpoint
为true
,该值包含于数列中 - num:要生成的等步长的样本数量,默认为
50
- endpoint:该值为
true
时,数列中包含stop
值,反之不包含,默认是True。 - base:对数 log 的底数。
- dtype:数组的元素类型
a = np.logspace(1, 3, num=3)
print(a)
#[ 10. 100. 1000.]
注意:默认是以10为底数的,可以理解为start是,end为。
创建对称矩阵
numpy.eye(N, M=None, k=0, dtype=float, order='C')
创建一个对称矩阵,矩阵的对角线上的值为1,其他值为0。
x = np.eye(5)
print(x)
’’’
[[1. 0. 0. 0. 0.][0. 1. 0. 0. 0.][0. 0. 1. 0. 0.][0. 0. 0. 1. 0.][0. 0. 0. 0. 1.]]
‘’‘
参数说明:
- N为矩阵的列数
- M为矩阵的行数,默认等于N
- k表示对角线1的偏移量
x = np.eye(3, k=1)
print(x)
‘’'
[[0. 1. 0.][0. 0. 1.][0. 0. 0.]]
‘’'x = np.eye(3, k=-1)
print(x)
‘’'
[[0. 0. 0.][1. 0. 0.][0. 1. 0.]]
‘''
索引和切片
下标
NumPy数组可以直接通过下标进行访问,下标从0开始,每个下标代表一行数据,下标的下标代表一个元素,也可以直接用逗号分割各维度:
a = np.array([[1,2,3], [10,20,30]])
print(a[1]) #[10 20 30]
print(a[1][1]) #20
print(a[1,1]) #20
切片
NumPy数组也支持切片,通过冒号分隔切片参数 start:stop:step 来进行切片操作。
注意:对切片赋值是直接对数组赋值,会改变数据的值。
一维数组切片
对于一维数组,用法与Python列表一样:
a = np.arange(10)
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b) #[2 4 6]
print(a[2]) #2
print(a[2:]) #[2 3 4 5 6 7 8 9]
print(a[:2]) #[0 1]
print(a[2:7]) #[2 3 4 5 6]
print(a[::1]) #[0 1 2 3 4 5 6 7 8 9]
print(a[-2:]) #[8 9]
也支持负整数下标,最后一个数的负整数下标为-1,但因为矩阵比较复杂,而负整数为更进一步的增加表达的复杂度,除非是一维数组,一般不建议使用负整数下标.
冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取,如果未[:2],则提取到第2个值(不含2,开区间)。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。
如果前面的start和end都不指定,只指定step也是可以的,将根据步长取全部的数据。
多维数组切片
多维数组的切片,对于每一个维度,都是遵循一维的切片规则,不同的维度之间通过逗号分割。
a = np.array([[1,2,3,4], [10,20,30,40], [10, 100, 1000, 10000]])
print(a)
‘’'
[[ 1 2 3 4][ 10 20 30 40][ 10 100 1000 10000]]
‘''print(a[1:])
‘’'
[[ 10 20 30 40][ 10 100 1000 10000]]
‘’'print(a[:,1:])
‘’'
[[ 2 3 4][ 20 30 40][ 100 1000 10000]]
‘''
如果只想得到某一列,可以通过切片得到,如只想得到第3列:
a = np.array([[1,2,3,4], [10,20,30,40], [10, 100, 1000, 10000]])
print(a[:,2:3])
‘’'
[[ 3][ 30][1000]]
‘''
如果直接使用第2列的下标,但得到的不是列数据,而是转置为行的数据:
a = np.array([[1,2,3,4], [10,20,30,40], [10, 100, 1000, 10000]])print(a[:,2])
’’’
[ 3 30 1000]
‘’‘
如果维度很高,也可以通过...代替前面或后面的维数:
a = np.array([[1,2,3,4], [10,20,30,40], [10, 100, 1000, 10000]])
print(a[...,1]) #第2列元素
# [ 2 20 100]
print(a[1,...]) #第2行元素
#[10 20 30 40]
print (a[...,1:]) # 第2列及剩下的所有元素
'''
[[ 2 3 4][ 20 30 40][ 100 1000 10000]]
'''
切片赋值
也可以直接对切片进行赋值,切片是原数组的试图,对切片的赋值,会修改原数组的值。
a = np.array([[11,12,13], [21,22,23],[31,32,33]])
print(a)
‘''
[[11 12 13][21 22 23][31 32 33]]
‘’'print(a[0:2,1]) #[12 22]
a[0,1] = 100
a[0:2,1] = (101,102) #将会修改数组a的元素
print(a[0:2,1]) #[101 102]
print(a)
‘’'
[[ 11 101 13][ 21 102 23][ 31 32 33]]
‘’'b = a[0:2,2]
b[0] = 201 #也同样会修改a的元素
print(a)
’’’
[[ 11 101 201][ 21 102 23][ 31 32 33]]
‘’’b = (301,302) #这个不能修改a的元素,直接把b的引用指向了一个新的元组
print(a)
’’’
[[ 11 101 201][ 21 102 23][ 31 32 33]]
‘’’b = a[0:2,2]
b[:] = (301,302) #如果要修改b的全部元素,要这么样写才行,同样会修改a的元素
print(a)
’’’
[[ 11 101 301][ 21 102 302][ 31 32 33]]
‘’‘
整数数组索引
对于多维数组,也可以通过一个整数数组来访问。
以下实例获取数组中 (0,0),(1,1) 和 (2,0) 位置处的元素:
a = np.array([[1,2,3,4], [10,20,30,40], [10, 100, 1000, 10000]])
print(a)
‘’'
[[ 1 2 3 4][ 10 20 30 40][ 10 100 1000 10000]]
‘’'print(a[[0,1,2], [0,1,0]])
‘’'
[ 1 20 10]
‘''
布尔索引(条件过滤)
可以通过布尔索引做条件过滤。直接在中括号中写过滤条件:
x = np.array([[11, 12, 13],[21, 22, 23],[31, 32, 33],[41, 42, 43]])
print(x[x>21]) #[22 23 31 32 33 41 42 43]
print(x[x%2==0]) #[12 22 32 42]
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])#[ 1. 2. 3. 4. 5.]
花式索引
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。
对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素,如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。
x = np.array([[11,12,13,14,15],[21,22,23,24,25],[31,32,33,34,35],[41,42,43,44,45], [51,52,53,54,55], [61,62,63,64,65]])
print(x)
print(x[1]) #第2行
print(x[1,2]) #23
print(x[[1,2]]) #第2、3行
print(x[[1,2,3,4],[1,3,2,4]]) #表示获取x(1,1)、(2,3)、(3,2)、(4,4)四个元素,x[]里的第一个中括号是第0维,第2个中括号是第1维。’’’
[[11 12 13 14 15][21 22 23 24 25][31 32 33 34 35][41 42 43 44 45][51 52 53 54 55][61 62 63 64 65]]
[21 22 23 24 25]
23
[[21 22 23 24 25][31 32 33 34 35]]
[22 34 43 55]
‘’‘
从上面的例子可以看出,可以使用x[n]来获得第n+1行的数据,可以通过一个列表作为下标x[[n,m,..]]来获得多行的数据,这就是花式索引。
并且可以用行号重新组织数组,如下:
x = np.array([[11,12,13,14,15],[21,22,23,24,25],[31,32,33,34,35],[41,42,43,44,45], [51,52,53,54,55], [61,62,63,64,65]])
print(x)
print(x[[-1,-2,-3,-4]])‘’'
[[11 12 13 14 15][21 22 23 24 25][31 32 33 34 35][41 42 43 44 45][51 52 53 54 55][61 62 63 64 65]]
[[61 62 63 64 65][51 52 53 54 55][41 42 43 44 45][31 32 33 34 35]]
‘''
广播(数组运算)
广播(Broadcast)是 numpy 对不同维度(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求形状相同(维数相同,且各维度的长度也要相同)。
a = np.array([[1,2,3,4], [7,8,9,10]])
b = np.array([[10,20,30,40], [70,80,90,100]])
c1 = a * b
print(c1)
'''
[[ 10 40 90 160][ 490 640 810 1000]]
‘''c2 = a + b
print(c2)
‘’'
[[ 11 22 33 44][ 77 88 99 110]]
‘''c3 = b - a
print(c3)
‘’'
[[ 9 18 27 36][63 72 81 90]]
‘''c4 = b / a
print(c4)
‘’'
[[10. 10. 10. 10.][10. 10. 10. 10.]]
‘''
广播不是矩阵运算,是数组各元素按位置与对应另外一个数组的数学运算,将得到与数组一样的维度的数组。
当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制:
如果两个数组a,b的维数相同,但b的某一个维度或几个维度的长度为1,则会自动将该维度的数据复制进行伸展到与a的形状一致,再进行按元素位置对应的运算。极端情况,b只有一个元素,它可以横向、纵向的任意扩展(复制自己)
例子一:b是一个单一的数,单一的数可以向任何维度复制自己
a = np.array([[11,12,13,14], [21,22,23,24], [31,32,33,34]])
b = 1
c = a + b
print(c)
‘’'
[[12 13 14 15][22 23 24 25][32 33 34 35]]
‘''
例子二:b是一维数据
a = np.array([[11,12,13,14], [21,22,23,24], [31,32,33,34]])
b = np.array([2,2,2,2])
c = a + b
print(c)
‘’'
[[13 14 15 16][23 24 25 26][33 34 35 36]]
‘’'b = np.array([[3],[3],[3]])
c = a + b
print(c)
‘’'
[[14 15 16 17][24 25 26 27][34 35 36 37]]
‘''
无论是纵向还是横向,都会整行(或整列)复制自己。
但是,要求这一维数据的长度必须与a至少一个维度的长度相同,否则会出现
ValueError: operands could not be broadcast together with shapes
的错误。
a = np.array([[11,12,13,14], [21,22,23,24], [31,32,33,34]])
b = np.array([2,2,2])
c = a + b #ValueError: operands could not be broadcast together with shapes (3,4) (3,)
print(c)
例子三:三维度的例子
立方体与点的和:a上所有的值都会加上b,形成一个与a形状相同的立方体
a = np.array([[[11,12,13,14],[21,22,23,24],[31,32,33,34]],[[111,112,113,114],[121,122,123,124],[131,132,133,134]],[[211,212,213,214],[221,222,223,224],[231,232,233,234]]])
b = np.array(2)
c = a + b
print(c)’’’
[[[ 13 14 15 16][ 23 24 25 26][ 33 34 35 36]][[113 114 115 116][123 124 125 126][133 134 135 136]][[213 214 215 216][223 224 225 226][233 234 235 236]]]‘’‘
立方体与线段的和:线段会向横和纵两个方向扩展,a的每一组元素对应b的元素的位置进行加和,得到和a一样的形状的数组。
a = np.array([[[11,12,13,14],[21,22,23,24],[31,32,33,34]],[[111,112,113,114],[121,122,123,124],[131,132,133,134]],[[211,212,213,214],[221,222,223,224],[231,232,233,234]]])
# b = np.array(2)
# c = a + b
# print(c)b = np.array([100,101,102,103])
c = a + b
print(c)’’’
[[[111 113 115 117][121 123 125 127][131 133 135 137]][[211 213 215 217][221 223 225 227][231 233 235 237]][[311 313 315 317][321 323 325 327][331 333 335 337]]]
‘’‘
立方体和面的和:按面去加和。
a = np.array([[[11,12,13,14],[21,22,23,24],[31,32,33,34]],[[111,112,113,114],[121,122,123,124],[131,132,133,134]],[[211,212,213,214],[221,222,223,224],[231,232,233,234]]])b = np.array([[100,100,100,100],[200,200,200,200],[300,300,300,300]])
c = a + b
print(c)’’’
[[[111 112 113 114][221 222 223 224][331 332 333 334]][[211 212 213 214][321 322 323 324][431 432 433 434]][[311 312 313 314][421 422 423 424][531 532 533 534]]]
‘’‘
数组的常用方法
NumPy提供了大量操作数组的方法,这里列举几种常用的方法,有些有复杂机制的方法后面还会详细说明。
修改数组形状
方法 | 描述 |
---|---|
reshape | 不改变数据的条件下修改形状 |
flat | 数组元素迭代器 |
flatten | 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 |
ravel | 返回展开数组 |
resize | 返回指定形状的新数组 |
重新造形
numpy.reshape(newshape, order='C')
该方法在不改变数据的条件下修改形状。
参数说明:
- newshape:新的形状,可以是一个整数或者整数序列,也可以是展开的多个整数
- order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
import numpy as npa = np.arange(8)
print('原始数组:')
print(a)
print('\n')b = a.reshape(4, 2)
print('修改后的数组:')
print(b)‘’'
原始数组:
[0 1 2 3 4 5 6 7]修改后的数组:
[[0 1][2 3][4 5][6 7]]
‘''
修改数组大小
numpy.resize(arr, shape)
返回指定大小的新数组,如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
参数说明:
arr
:要修改大小的数组shape
:返回数组的新形状
import numpy as npa = np.array([[1,2,3],[4,5,6]])print ('第一个数组:')
print (a)
print ('\n')print ('第一个数组的形状:')
print (a.shape)
print ('\n')
b = np.resize(a, (3,2))print ('第二个数组:')
print (b)
print ('\n')print ('第二个数组的形状:')
print (b.shape)
print ('\n')
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了print ('修改第二个数组的大小:')
b = np.resize(a,(3,3))
print (b)‘’’
第一个数组:
[[1 2 3][4 5 6]]第一个数组的形状:
(2, 3)第二个数组:
[[1 2][3 4][5 6]]第二个数组的形状:
(3, 2)修改第二个数组的大小:
[[1 2 3][4 5 6][1 2 3]]
’‘’
访问全部元素迭代器
numpy.ndarray.flat
一个数组元素迭代器,可以访问全部的数组元素。
import numpy as npa = np.arange(9).reshape(3,3)
print ('原始数组:')
for row in a:print (row)#对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print ('迭代后的数组:')
for element in a.flat:print (element)’’’
原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8
‘’‘
展开数组(复制)
ndarray.flatten(order='C')
返回一份数组拷贝并且将多维数组展开,对拷贝所做的修改不会影响原始数组。
参数说明:
- order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
import numpy as npa = np.arange(8).reshape(2,4)print ('原数组:')
print (a)
print ('\n')
# 默认按行print ('展开的数组:')
print (a.flatten())
print ('\n')print ('以 F 风格顺序展开的数组:')
print (a.flatten(order = 'F’))’’’
原数组:
[[0 1 2 3][4 5 6 7]]展开的数组:
[0 1 2 3 4 5 6 7]以 F 风格顺序展开的数组:
[0 4 1 5 2 6 3 7]
‘’‘
展开数组(视图)
numpy.ravel(order='C')
返回原数组的展开数组,返回的是数组视图,修改会影响原始数组。
参数说明:
- order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
import numpy as npa = np.arange(8).reshape(2, 4)
print('原数组a:\n', a)
b = a.flatten()
print('flatten展开的数组b:\n', b)
c = a.ravel()
print ('ravel展开的数组c:\n', c)b[1] = 10
print('修改b[1]后数组b:\n', b)
print('修改b[1]后数组a:\n', a) #a并没有变化
c[1] = 10
print('修改c[1]后数组b:\n', c)
print('修改c[1]后数组a:\n', a) #a的元素值改变了’’’
原数组a:[[0 1 2 3][4 5 6 7]]
flatten展开的数组b:[0 1 2 3 4 5 6 7]
ravel展开的数组c:[0 1 2 3 4 5 6 7]
修改b[1]后数组b:[ 0 10 2 3 4 5 6 7]
修改b[1]后数组a:[[0 1 2 3][4 5 6 7]]
修改c[1]后数组b:[ 0 10 2 3 4 5 6 7]
修改c[1]后数组a:[[ 0 10 2 3][ 4 5 6 7]]
‘’‘
数组变换
函数 | 描述 |
---|---|
transpose | 转置:对换数组的维度 |
ndarray.T | 和 self.transpose() 相同 |
rollaxis | 向后滚动指定的轴 |
swapaxes | 对换数组的两个轴 |
转置T
numpy.transpose(axes)
返回转置的数组。
参数说明:
- axes:整数列表,对应维度,通常所有维度都会对换。
a = np.arange(12).reshape(4, 3)
print('原数组a:\n', a)
‘’’
原数组a:[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11]]
’’’print('a转置后:\n', a.transpose())
‘’’
a转置后:[[ 0 3 6 9][ 1 4 7 10][ 2 5 8 11]]
’‘’
可以指定转置的轴,0相当于x轴,1相当于y轴,...,以此类推。上面的例子是二维的,如果指定为tanspose(0,1)相当于没有转置,返回的就是与原来一样的数组,如果是tanspose(1,0)返回的就是转置数组。
a = np.arange(12).reshape(4, 3)
print('原数组a:\n', a)
‘’’
原数组a:[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11]]
’’’print('transpose(0,1):\n', a.transpose(0,1))
‘’’
transpose(0,1):[[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11]]
’’’print('transpose(1,0):\n', a.transpose(1,0))
‘’’
transpose(1,0):[[ 0 3 6 9][ 1 4 7 10][ 2 5 8 11]]
’‘’
对于高维数组,可以任意的排列各轴:
a = np.arange(36).reshape(4, 3, 3)
print('原数组a:\n', a)
print('transpose(0,2,1):\n', a.transpose(0,2,1))
也可以直接用numpy.T来表示转置:
a = np.arange(12).reshape(4, 3)
print('原数组a:\n', a)
# print('transpose(0,1):\n', a.transpose(0,1))
print('transpose(1,0):\n', a.transpose(1,0))
print(a.T) #与a.transpose(1,0)相同
滚动轴
numpy.rollaxis(a, axis, start)
向后滚动特定的轴到一个特定位置
参数说明:
- a:待滚动的数组
axis
:要向后滚动的轴,其它轴的相对位置不会改变start
:默认为零,表示完整的滚动。会滚动到特定位置。
先看二维的情况:
a = np.arange(6).reshape(3, 2)
print(a)
print('滚动轴:\n', np.rollaxis(a, 1))‘’’
[[0 1][2 3][4 5]]
滚动轴:[[0 2 4][1 3 5]]
’‘’
从效果来看就是转置。
再看三维的情况:
a = np.arange(24).reshape(2, 3, 4)
print('原数组a:\n', a)
print('滚动轴:\n', np.rollaxis(a, 1))‘’'
原数组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]]]
滚动轴:[[[ 0 1 2 3][12 13 14 15]][[ 4 5 6 7][16 17 18 19]][[ 8 9 10 11][20 21 22 23]]]
‘''
数组(2,3,4)变化为(3,2,4),可以看出0轴和1轴进行了变换。
交换轴
numpy.swapaxes(arr, axis1, axis2)
交换数组的两个轴
参数说明:
arr
:输入的数组axis1
:对应第一个轴的整数axis2
:对应第二个轴的整数
a = np.arange(24).reshape(2, 3, 4)
print('原数组a:\n', a)
print('滚动轴:\n', np.rollaxis(a, 1))
print('交换轴:\n', np.swapaxes(a, 1, 0))‘’’
原数组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]]]
滚动轴:[[[ 0 1 2 3][12 13 14 15]][[ 4 5 6 7][16 17 18 19]][[ 8 9 10 11][20 21 22 23]]]
交换轴:[[[ 0 1 2 3][12 13 14 15]][[ 4 5 6 7][16 17 18 19]][[ 8 9 10 11][20 21 22 23]]]
’‘’
从上例子可以看到,滚动轴和交换1,0轴是一样的,这两个方法在某些场景有相同的效果。
修改数组维度
函数 | 描述 |
---|---|
broadcast | 产生模仿广播的对象 |
broadcast_to | 将数组广播到新形状 |
expand_dims | 扩展数组的形状 |
squeeze | 从数组的形状中删除一维条目 |
产生模仿广播的对象
numpy.broadcast(x,y)
扩展y,让它能按照广播的原则按x的形状进行扩展。
numpy.broadcast_to(array, shape, subok=False)
将数组广播到新形状
- array:要广播的数组
- shape:新形状
- subok:如果为True,则为子类,否则默认情况下,返回的数组将被强制为base-class数组
函数将数组广播到新形状。 它在原始数组上返回只 读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
x = np.arange(12).reshape(3, 4)
y = np.array([2,2,2,2])
y1 = np.broadcast_to(y, x.shape)
print(y1)‘’'
[[2 2 2 2][2 2 2 2][2 2 2 2]]
‘''
扩展数组的维度
numpy.expand_dims(arr, axis)
通过在指定位置插入新的轴来扩展数组形状
参数说明:
arr
:输入数组axis
:新轴插入的位置
x = np.array([[11,12],[21,22]])
print('原始数组:\n', x)
y = np.expand_dims(x, axis = 0)
print('插入维度后的数组:\n', y)
y = np.expand_dims(x, axis = 1)
print('插入维度后的数组:\n', y)‘’'
原始数组:[[11 12][21 22]]
插入维度后的数组:[[[11 12][21 22]]]
插入维度后的数组:[[[11 12]][[21 22]]]‘''
删除单维度
numpy.squeeze(arr, axis)
从数组的形状中删除单维度条目,即把shape中为1的维度去掉
参数说明:
arr
:输入数组axis
:整数或整数元组,指定需要删除的维度,但是指定的维度必须为单维度,否则将会报错;axis的取值可为None 或 int 或 tuple of ints, 可选。若axis为空,则删除所有单维度的条目;
x = np.arange(12).reshape(1, 3, 4)
print('原始数组:\n', x)
y = np.squeeze(x)
print('删除1轴后:\n', y)‘’’
原始数组:[[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]]]
删除1轴后:[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]]
’‘’
连接数组
函数 | 描述 |
---|---|
concatenate | 连接沿现有轴的数组序列 |
stack | 沿着新的轴加入一系列数组。 |
hstack | 水平堆叠序列中的数组(列方向) |
vstack | 竖直堆叠序列中的数组(行方向) |
沿轴连接
numpy.concatenate((a1, a2, ...), axis)
函数用于沿指定轴连接相同形状的两个或多个数组
参数说明:
a1, a2, ...
:相同形状的数组axis
:沿着它连接数组的轴,默认为 0
import numpy as npa = np.array([[1,2],[3,4]])print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])print ('第二个数组:')
print (b)
print ('\n')
# 两个数组的维度相同print ('沿轴 0 连接两个数组:')
print (np.concatenate((a,b)))
print ('\n')print ('沿轴 1 连接两个数组:')
print (np.concatenate((a,b),axis = 1))‘’’
第一个数组:
[[1 2][3 4]]第二个数组:
[[5 6][7 8]]沿轴 0 连接两个数组:
[[1 2][3 4][5 6][7 8]]沿轴 1 连接两个数组:
[[1 2 5 6][3 4 7 8]]
’‘’
numpy.stack(arrays, axis)
函数用于沿轴连接数组序列
参数说明:
arrays
相同形状的数组序列axis
:返回数组中的轴,输入数组沿着它来堆叠
import numpy as npa = np.array([[1,2],[3,4]])print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])print ('第二个数组:')
print (b)
print ('\n')print ('沿轴 0 堆叠两个数组:')
print (np.stack((a,b),0))
print ('\n')print ('沿轴 1 堆叠两个数组:')
print (np.stack((a,b),1))‘’’
第一个数组:
[[1 2][3 4]]第二个数组:
[[5 6][7 8]]沿轴 0 堆叠两个数组:
[[[1 2][3 4]][[5 6][7 8]]]沿轴 1 堆叠两个数组:
[[[1 2][5 6]][[3 4][7 8]]]
’‘’
水平堆叠
numpy.hstack(arrays)
numpy.stack 函数的变体,它通过水平堆叠来生成数组
import numpy as npa = np.array([[1,2],[3,4]])print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])print ('第二个数组:')
print (b)
print ('\n')print ('水平堆叠:')
c = np.hstack((a,b))
print (c)
print ('\n’)‘’’
第一个数组:
[[1 2][3 4]]第二个数组:
[[5 6][7 8]]水平堆叠:
[[1 2 5 6][3 4 7 8]]
‘''
垂直堆叠
numpy.vstack(arrays)
numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
import numpy as npa = np.array([[1,2],[3,4]])print ('第一个数组:')
print (a)
print ('\n')
b = np.array([[5,6],[7,8]])print ('第二个数组:')
print (b)
print ('\n')print ('竖直堆叠:')
c = np.vstack((a,b))
print (c)‘’'
第一个数组:
[[1 2][3 4]]第二个数组:
[[5 6][7 8]]竖直堆叠:
[[1 2][3 4][5 6][7 8]]
‘''
分割数组
函数 | 数组及操作 |
---|---|
split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
沿轴分割
numpy.split(ary, indices_or_sections, axis)
参数说明:
ary
:被分割的数组indices_or_sections
:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)axis
:设置沿着哪个方向进行切分,默认为 0,横向切分,即水平方向。为 1 时,纵向切分,即竖直方向。
import numpy as npa = np.arange(9)print ('第一个数组:')
print (a)
print ('\n')print ('将数组分为三个大小相等的子数组:')
b = np.split(a,3)
print (b)
print ('\n')print ('将数组在一维数组中表明的位置分割:')
b = np.split(a,[4,7])
print (b)‘’’
第一个数组:
[0 1 2 3 4 5 6 7 8]将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]将数组在一维数组中表明的位置分割:
[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
’‘’
axis 为 0 时在水平方向分割,axis 为 1 时在垂直方向分割:
import numpy as npa = np.arange(16).reshape(4, 4)
print('第一个数组:')
print(a)print('默认分割(0轴):')
b1,b2 = np.split(a,2)
print('数组1:\n', b1,'\n数组2:\n', b2)print('沿纵向分割:')
c1,c2 = np.split(a,2,1)
print('数组1:\n', c1,'\n数组2:\n', c2)‘’’
第一个数组:
[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11][12 13 14 15]]
默认分割(0轴):
数组1:[[0 1 2 3][4 5 6 7]]
数组2:[[ 8 9 10 11][12 13 14 15]]
沿纵向分割:
数组1:[[ 0 1][ 4 5][ 8 9][12 13]]
数组2:[[ 2 3][ 6 7][10 11][14 15]]
‘''
水平分割
numpy.hsplit(ary, indices_or_sections)
用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组
垂直分割
numpy.vsplit(ary, indices_or_sections)
沿着垂直轴分割,其分割方式与hsplit用法相同。
数组元素的添加与删除
函数 | 元素及描述 |
---|---|
append | 将值添加到数组末尾 |
insert | 沿指定轴将值插入到指定下标之前 |
delete | 删掉某个轴的子数组,并返回删除后的新数组 |
unique | 查找数组内的唯一元素 |
末尾添加值
numpy.append(arr, values, axis=None)
函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。返回的始终是一个一维数组。
参数说明:
arr
:输入数组values
:要向arr
添加的值,需要和arr
形状相同(除了要添加的轴)axis
:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
import numpy as npa = np.array([[1, 2, 3], [4, 5, 6]])print('第一个数组:\n', a)print('向数组添加元素:')
print(np.append(a, [7, 8, 9]))print('沿轴 0 添加元素:')
print(np.append(a, [[7, 8, 9]], axis=0))print('沿轴 1 添加元素:')
print(np.append(a, [[10, 11, 12], [21, 22, 23]], axis=1))‘’’
第一个数组:[[1 2 3][4 5 6]]
向数组添加元素:
[1 2 3 4 5 6 7 8 9]
沿轴 0 添加元素:
[[1 2 3][4 5 6][7 8 9]]
沿轴 1 添加元素:
[[ 1 2 3 10 11 12][ 4 5 6 21 22 23]]
’‘’
按索引插入值
numpy.insert(arr, obj, values, axis)
在给定索引之前,沿给定轴在输入数组中插入值,将返回一个新数组。如果未提供轴,则输入数组会被展开。
参数说明:
arr
:输入数组obj
:在其之前插入值的索引values
:要插入的值axis
:沿着它插入的轴,如果未提供,则输入数组会被展开;传递了 Axis 参数。 会广播值数组来配输入数组。
import numpy as npa = np.arange(12).reshape(3,4)
print('第一个数组:\n', a)
print('未传递 Axis 参数。 在3前插入[100, 200]之前输入数组会被展开。')
print(np.insert(a, 3, [100, 200]))#传递了 Axis 参数。 会广播值数组来配输入数组
print('指定0轴的2行(0行开始)前插入[100,101,102,103]:')
print(np.insert(a, 2, [100,101,102,103], axis=0))
print('指定0轴的2行(0行开始)前插入[100],按广播扩展:')
print(np.insert(a, 2, [100], axis=0))print('指定1轴的3列前插入[100,101,102](会自动转置):')
print(np.insert(a, 3, [100,101,102], axis=1))
print('指定1轴的3列前插入[100],按广播扩展:')
print(np.insert(a, 3, 100, axis=1))‘’’
第一个数组:[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]]
未传递 Axis 参数。 在3前插入[100, 200]之前输入数组会被展开。
[ 0 1 2 100 200 3 4 5 6 7 8 9 10 11]
指定0轴的2行(0行开始)前插入[100,101,102,103]:
[[ 0 1 2 3][ 4 5 6 7][100 101 102 103][ 8 9 10 11]]
指定0轴的2行(0行开始)前插入[100],按广播扩展:
[[ 0 1 2 3][ 4 5 6 7][100 100 100 100][ 8 9 10 11]]
指定1轴的3列前插入[100,101,102](会自动转置):
[[ 0 1 2 100 3][ 4 5 6 101 7][ 8 9 10 102 11]]
指定1轴的3列前插入[100],按广播扩展:
[[ 0 1 2 100 3][ 4 5 6 100 7][ 8 9 10 100 11]]
’‘’
删除指定子数组
Numpy.delete(arr, obj, axis)
返回从输入数组中删除指定子数组的新数组,与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。
参数说明:
arr
:输入数组obj
:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组axis
:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
import numpy as npa = np.arange(12).reshape(3,4)
print('第一个数组:\n', a)
print('删除元素5,未传递 Axis 参数,在插入之前输入数组会被展开。')
print(np.delete(a, 5))print('如果指定轴1,删除第二列:')
print(np.delete(a, 1, axis=1))print('包含从数组中删除的替代值的切片:')
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(np.delete(a, np.s_[::2]))‘’’
第一个数组:[[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]]
删除元素5,未传递 Axis 参数,在插入之前输入数组会被展开。
[ 0 1 2 3 4 6 7 8 9 10 11]
如果指定轴1,删除第二列:
[[ 0 2 3][ 4 6 7][ 8 10 11]]
包含从数组中删除的替代值的切片:
[ 2 4 6 8 10]
’‘’
数组去重
numpy.unique(arr, return_index, return_inverse, return_counts)
返回见下面的说明
参数说明:
arr
:输入数组,如果不是一维数组则会展开return_index
:如果为true
,返回新列表元素在旧列表中的位置(下标),并以列表形式储return_inverse
:如果为true
,返回旧列表元素在新列表中的位置(下标),并以列表形式储return_counts
:如果为true
,返回去重数组中的元素在原数组中的出现次数
import numpy as npa = np.array([[1,2,3,4],[1,2,3,4],[4,5,6,7]])
print('待去重的数组:\n', a)print('去重:\n', np.unique(a))print('去重索引数组:')
u, indices = np.unique(a, return_index=True)
print(indices)print('去重下标:')
u, indices = np.unique(a, return_inverse=True)
print(indices)print('返回去重元素的重复数量:')
u, indices = np.unique(a, return_counts=True)
print(indices)‘’'
待去重的数组:[[1 2 3 4][1 2 3 4][4 5 6 7]]
去重:[1 2 3 4 5 6 7]
去重索引数组:
[ 0 1 2 3 9 10 11]
去重下标:
[0 1 2 3 0 1 2 3 3 4 5 6]
返回去重元素的重复数量:
[2 2 2 3 1 1 1]
‘''
相关文章:
Python的NumPy库(一)基础用法
NumPy库并不是Python的标准库,但其在机器学习、大数据等很多领域有非常广泛的应用,NumPy本身就有比较多的内容,全部的学习可能涉及许多的内容,但我们在这里仅学习常见的使用,这些内容对于我们日常使用NumPy是足够的。 …...
uniapp app 导出excel 表格
直接复制运行 <template><view><button click"tableToExcel">导出一个表来看</button><view>{{ successTip }}</view></view> </template><script>export default {data() {return {successTip: }},metho…...
【RabbitMQ】常用消息模型详解
文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…...
图像拼接后丢失数据,转tiff报错rasterfile failed: an unknown
图像拼接后丢失数据 不仅是数据丢失了,还有个未知原因报错 部分数据存在值不存在的情况 原因 处理遥感数据很容易,磁盘爆满了 解决方案 清理一些无用数据,准备买个2T的外接硬盘用着了。 然后重新做处理...
Nginx之日志模块解读
目录 基本介绍 配置指令 access_log(访问日志) error_log( 错误日志) 基本介绍 Nginx日志主要分为两种:access_log(访问日志)和error_log(错误日志)。Nginx日志主要记录以下信息: 记录Nginx服务启动…...
latex方程组编写,一种可以保证方程编号自适应的方法
问题描述: 在利用latex编写方程组时,可以有很多种方法,但不总是编辑好的公式能够显示出编号,故提出一种有效的方程组编写方法 方法: \begin{equation}X_{ t1}\left \{ \begin{matrix}\frac{x_{i}}{a} \quad\quad 0&l…...
深度学习基础 2D卷积(1)
什么是2D卷积 2D参数量怎么计算 以pytorch为例子,2D卷积在设置的时候具有以下参数,具有输入通道的多少(这个决定了卷积核的通道数量),滤波器数量,这个是有多少个滤波器,越多提取的特征就越有用…...
OpenCV DNN C++ 使用 YOLO 模型推理
OpenCV DNN C 使用 YOLO 模型推理 引言 YOLO(You Only Look Once)是一种流行的目标检测算法,因其速度快和准确度高而被广泛应用。OpenCV 的 DNN(Deep Neural Networks)模块为我们提供了一个简单易用的 API࿰…...
第八章 Linux文件系统权限
目录 8.1 文件的一般权限 1.修改文件或目录的权限---chmod命令 2.对于文件和目录,r,w,x有不同的作用: 3.修改文件或目录的所属主和组---chown,chgrp 8.2 文件和目录的特殊权限 三种通过字符描述文件权限 8.3 ACL 权限 1.A…...
XXL-JOB源码梳理——一文理清XXL-JOB实现方案
分布式定时任务调度系统 流程分析 一个分布式定时任务,需要具备有以下几点功能: 核心功能:定时调度、任务管理、可观测日志高可用:集群、分片、失败处理高性能:分布式锁扩展功能:可视化运维、多语言、任…...
java做个qq机器人
前置的条件 机器人是基于mirai框架实现的。根据官方的文档,建议使用openjdk11。 我这里使用的编辑工具是idea2023 在idea中新建一个maven项目,虽然可以使用gradle进行构建,不过我这里由于网络问题没有跑通。 pom.xml <dependency>&l…...
前端 | AjaxAxios模块
文章目录 1. Ajax1.1 Ajax介绍1.2 Ajax作用1.3 同步异步1.4 原生Ajax 2. Axios2.1 Axios下载2.2 Axios基本使用2.3 Axios方法 1. Ajax 1.1 Ajax介绍 Ajax: 全称(Asynchronous JavaScript And XML),异步的JavaScript和XML。 1.2 Ajax作用 …...
高效的ProtoBuf
一、背景 Google ProtoBuf介绍 这篇文章我们讲了怎么使用ProtoBuf进行序列化,但ProtoBuf怎么做到最高效的,它的数据又是如何压缩的,下面先看一个例子,然后再讲ProtoBuf压缩机制。 二、案例 网上有各种序列化方式性能对比&#…...
删除SQL记录
删除记录的方式汇总: 根据条件删除:DELETE FROM tb_name [WHERE options] [ [ ORDER BY fields ] LIMIT n ] 全部删除(表清空,包含自增计数器重置):TRUNCATE tb_namedelete和truncate的区别: d…...
数据结构--》探索数据结构中的字符串结构与算法
本文将带你深入了解串的基本概念、表示方法以及串操作的常见算法。通过深入理解串的相关概念和操作,我们将能够更好地应用它们来解决算法问题。 无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握串在数据…...
云安全之等级保护详解
等级保护概念 网络安全等级保护,是对信息系统分等级实行安全保护,对信息系统中使用的安全产品实行按等级管理,对信息系统中发生的信息安全事件分等级进行响应、处置。 网络安全等级保护的核心内容是:国家制定统一的政策、标准&a…...
VUE状态持久化,储存动态路由
1. vuex persistPlugin.js 文件 const routerKey "ROUTER_KEY";export default (store) > {// 刷新页面时,存储改变的数据window.addEventListener("beforeunload", () > {localStorage.setItem(routerKey, JSON.stringify(store.stat…...
微信小程序代驾系统源码(含未编译前端,二开无忧) v2.5
简介: 如今有越来越多的人在网上做代驾,打造一个代驾平台,既可以让司机增加一笔额外的收入,也解决了车主酒后不能开发的问题,代驾系统基于微信小程序开发的代驾系统支持一键下单叫代驾,支持代驾人员保证金…...
1797_GNU pdf阅读器evince
全部学习汇总: GreyZhang/g_GNU: After some years I found that I do need some free air, so dive into GNU again! (github.com) 近段时间经历了很多事情,终于想找一点技术上的自由气氛。或许,没有什么比GNU的一些软件探索更适合填充这样的…...
网络-跨域解决
文章目录 前言一、跨域是什么?二、跨域的解决1.JSONP2.前端代理dev环境3.后端设置请求头CORS4.运维nginx代理 总结 前言 本文主要介绍跨域问题介绍并提供了四种解决办法。 一、跨域是什么? 准确的来说是浏览器存在跨域问题,浏览器为了安全考…...
git提交代码的流程
1.拉取代码 当你进入了一家公司就需要拉去公司的代码进行开发,此时你的项目小组长会给你个地址拉代码, git clone 公司项目的地址 此时如果不使用了这个方式拉去代码,拉去的是master分支上的代码,但是很多数的情况下,公司的项目可能会在其它的分支上,因此到公…...
【SpringBoot】配置文件详解
配置文件详解 一. 配置文件作用二. 配置文件的格式1. properties 配置文件说明①. properties 基本语法②. 读取配置⽂件③. properties 缺点 2. yml 配置⽂件说明①. yml 基本语法②. yml 使用进阶 3. properties VS yml 三. 设置不同环境的配置⽂件 一. 配置文件作用 整个项…...
一文讲懂-五险一金
假设在“北京”:这里的数值并不代表任何真实的城市或地区,只是为了说明计算方法。 工资: 月工资为 6000 元。养老保险: 单位比例: 20% 个人比例: 8%医疗保险: 单位比例: 10% 个人比例: 2%失业保险: 单位比例: 2% 个人比例: 0.5%工伤保险: 单位比例: 0.5…...
判断三条边是否构成三角形(Python实现)
组成三角形的三条边a,b,c需满足条件: ab>c ac>b bc>a 已知:三角形任意三条边的长度之和大于第三条边。 解题:定义3个变量a、b、c,让用户输入任意三个数字赋值给三个变量。判断三个变量中是否任意两个之和大于第三个数值。 判断条件之…...
The directory ‘*‘ or its parent directory is not owned by the current user
python安装编译时出现如下错误 The directory /home/admin/.cache/pip/http or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may …...
leetcode做题笔记162. 寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O(…...
nginx负载转发源请求http/https:X-Forwarded-Proto及nginx中的转发报头
今天在排查服务器的问题时最后定位到服务器因为经过了运维这一层的处理,转发过来的请求不管用户请求的是https还是http,我们的proxy服务器收到的都是80端口上的http。于是联系相关部门了解有没有现成的可用的这样一个字段来获得这个值。公司用的也是标准…...
Docker compose插件安装
添加docker源 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/do…...
【数据结构与算法】树、二叉树的概念及结构(详解)
前言: 💥🎈个人主页:Dream_Chaser~ 🎈💥 ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--树以及二叉树的概念与结构 目录 一.树概念及结构 1.树的概念 1.1树与非树 树的特点࿱…...
函数指针数组指针(指向函数指针数组的指针)
一、什么是函数指针数组指针? 本质是指针,指向函数指针数组,存放函数指针数组的地址。 代码如下: pfArr是函数指针数组 p是函数指针数组指针 int main() {int(*pfArr[])(int, int) { Add,Sub };//函数指针数组int(*(*p)[])(int, …...
wordpress政府网站/网店怎么推广和宣传
上一篇博文主要通过两个例子让测试新手了解一下测试思想,和在做测试之前应该了解人几点,那么我们在如何完成一次完整的性能测试呢? 测试报告是一次完整性能测试的体现,所以,这里我给出一个完整的性能测试报告ÿ…...
nodejs做网站还是app/google play store
电子商务平台源码请加企鹅求求:一零三八七七四六二六。在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用传统的session方式来解决,我想已经ou…...
阳江公司做网站/网站优化排名推荐
如果你正在使用sass、less或coffee,而没有注意到koala, 那说明你可能已经好久没有更新你的知识库了。koala这个由国人编写的,用于编译sass、less、coffee利器,在最近的短短几个月曝光率不亚 于任何其他的技术。当然这跟其作者的辛…...
动态网站建设实训心得体会/seo推广知识
随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)、QQ技术交流群(183198395)。 接上一文继续研究Fragment的使用,本文主要实现这样一个简单应用:左边显示标题栏,然后点击它&…...
公司起名字大全免费4个字/百度刷排名优化软件
一、后台下载/上传 1、简介 使用BackgroundTransferGroup可以十分方便操作上传及下载文件,BackgroundDownloader和BackgroundUploader类中的方法提供一系列方法交互这一过程,因此我们也可以利用live tile或toast显示传输的状态。 2、下载代码 代码一&…...
wordpress响应式音乐播放器/今日新闻最新消息大事
在前面的文章中,我们说直流减速电机的控制,不外乎控制两个量就好了,一个是方向一个是速度。今天我们就来说说怎么使用单片机或者其它控制器来对直流减速电机的方向进行控制。我们都有这么一个通识的认知:对于直流电机,…...