文章目录
一、numpy介绍
1.ndarray介绍
NumPy最核心的数据类型是N维数组(The N-dimensional array(ndarry))。
-
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
-
ndarray 对象是用于存放同类型元素的多维数组。
-
数组:数组(Array)是有序的元素序列,在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。
2.python列表和Numpy数组的区别
-
列表list与数组array的定义:
列表是由一系列按特定顺序排列的元素组成,可以将任何东西加入列表中,其中的元素之间没有任何关系;Python中的列表(list)用于顺序存储结构。它可以方便、高效的的添加删除元素,并且列表中的元素可以是多种类型。
数组也就是一个同一类型的数据的有限集合。 -
列表list与数组array的相同点:都可以根据索引来取其中的元素;
-
列表list与数组array的不同点:
a.列表list中的元素的数据类型可以不一样。数组array里的元素的数据类型一般是一样的;
b.列表list不可以进行数学四则运算,数组array可以进行数学四则运算;
二、NumPy 基础
1.ndarry数组
用np.ndarry类的对象表示n为数组
import numpy as np
ary=np.array([1,2,3,4,5,6])
print(ary,type(ary))
#输出
#[1 2 3 4 5 6] <class 'numpy.ndarray'>
2.内存中的ndarry对象
元数据(metadate)
存储对目标数组的描述信息,如:dim count (维数),shape(维度),size(元素个数),dtype(数组中每个元素的类型),data(指针,指向实际数据)
实际数据
完整的数组数据
将实际数据与元数据分开存放,一方面提高了内存空间的使用效率,另一方面减少对实际数据的访问频率,提高性能
3.ndarry数组对象的创建
np.array
import numpy as np
a=np.array([1,2,3,4,5,6])
print(a)
np.arange(起始值(0),终止值,步长(1))
import numpy as np
a=np.arange(0,5,1)
print(a) #[0 1 2 3 4]
b=np.arange(0,10,2)
print(b) #[0 2 4 6 8]
np.zeros(数组元素个数,dtype=‘类型’)
import numpy as np
a=np.zeros(10)
print(a) #[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] float64
b=np.zeros(10,dtype=int)
print(b) #[0 0 0 0 0 0 0 0 0 0]
np.ones(数组元素个数,dtype=‘类型’)
import numpy as np
a=np.ones(10)
print(a) #[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] float64
b=np.ones(10,dtype=int)
print(b) #[1 1 1 1 1 1 1 1 1 1]
np.zeros_like() 与 np.ones_like()
import numpy as np
a=np.ones(10)
print(np.zeros_like(a)) #[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 维度像a
b=np.ones(10,dtype=int)
print(np.ones_like(b)) #[1 1 1 1 1 1 1 1 1 1] 维度像b
4.ndarry对象属性的基本操作
数组的维度:np.ndarray.shape
import numpy as np
arr=np.array([1,2,3,4,5,6])
print(type(arr),arr,arr.shape) #<class 'numpy.ndarray'> [1 2 3 4 5 6] (6,) 一维数组,6个元素
#二维数组
arr=np.array([
[1,2,3,4],
[5,6,7,8]
])
print(type(arr),arr,arr.shape) #<class 'numpy.ndarray'> [[1 2 3 4]
# [5 6 7 8]] (2, 4)
元素的数据类型:np.ndarray.dtype
import numpy as np
arr=np.array([1,2,3,4,5,6])
print(type(arr),arr,arr.dtype) #<class 'numpy.ndarray'> [1 2 3 4 5 6] int32
#转换arr元素的类型
b=arr.astype(float)
print(type(b),b,b.dtype) #<class 'numpy.ndarray'> [1. 2. 3. 4. 5. 6.] float64
#转换arr元素的类型
c=arr.astype(str)
print(type(c),c,c.dtype) #<class 'numpy.ndarray'> ['1' '2' '3' '4' '5' '6'] <U11
数组元素的个数:np.ndarray.size
import numpy as np
arr=np.array([
[1,2,3,4],
[5,6,7,8]
])
print(arr.shape,arr.size,len(arr)) #(2, 4) 8 2
数组元素索引(下标)
数组对象[…,页号,行号,列号]
import numpy as np
a=np.array([[[1,2],
[3,4]],
[[5,6],
[7,8]]])
print(a,a.shape)
print(a[0])
print(a[0][0])
print(a[0][0][0])
print(a[0,1,0])
"""
[[[1 2]
[3 4]]
[[5 6]
[7 8]]] (2, 2, 2)
[[1 2]
[3 4]]
[1 2]
1
3
"""
#三层for循环输出元素
for i in range(a.shape[0]):
for j in range(a.shape[1]):
for k in range(a.shape[2]):
print(a[i][j][k])
5.ndarray对象属性操作详解
ndarray不能存储对象
Numpy的内部基本数据类型
布尔型 | bool |
---|---|
有符号整数型 | int8(-128~127)/int16/int32/int64 |
无符号整数型 | uint8(0~255)/uint16/uint/32/uint64 |
浮点型 | float16/float32/float64 |
复数型 | complex64/complex128 |
字串型 | str,每个字符用32位Unicode编码表示 |
自定义复合类型:
#自定义复合类型
import numpy as np
data=[
('zs',[90,80,85],15),
('ls',[92,81,83],16),
('ww',[95,85,95],15)
]
# 第一种设置dtype的方式
a=np.array(data,dtype='U2,3int32,int32') # U2表示Unicode字符出现两个
print(a) #[('zs', [90, 80, 85], 15) ('ls', [92, 81, 83], 16)
#('ww', [95, 85, 95], 15)]
print("---------------------")
#第二种设置dtype的方式
b=np.array(data,dtype=[('name','str_',2),
('score','int32',3),
('age','int32',1)])
print(b[0]['name'],":",b[0]['score']) # zs : [90 80 85]
print("---------------------")
#第三种设置dtype的方式
c=np.array(data,dtype={'names':['name','score','ages'],
'formats':['U3','3i4','int32']}) # i4代表int32
print(c[0]['name'],":",c[0]['score'],":",c.itemsize) #zs : [90 80 85] : 28 itemsize输出元素字节数
print("----------------------")
# 测试数组中存储日期数据类型
dates=['2011-01-01','2011','2011-02','2012-01-01','2012-02-01 10:10:00']
dates=np.array(dates)
print(dates,dates.dtype) # ['2011-01-01' '2011' '2011-02' '2012-01-01' '2012-02-01 10:10:00'] <U19
# <U19表示出现的Unicode字符小于19个
# 类型转换
dates=dates.astype('M8[D]')
print(dates,dates.dtype) # ['2011-01-01' '2011-01-01' '2011-02-01' '2012-01-01' '2012-02-01'] datetime64[D]
# datetime64 代表M8 [D]代表精确度 Day
6.类型字符码
类型 | 字符码 |
---|---|
np.bool | ? |
np.int8/16/32/64 | i1/i2/i4/i8 |
np.uint8/16/32/64 | u1/u2/u4/u8 |
np.float16/32/64 | f2/f4/f8 |
np.complex64/128 | c8/c16 |
np.str | U<字符数> |
np.datetime64 | M8[Y] M8[M] M8[D] M8[h] M8[m] M8[s] |
三、 ndarray维度操作
1.视图变维
(数据共享):reshap()与ravel()
# ndarry数组对象的维度操作
import numpy as np
a=np.arange(1,9)
print(a) #[1 2 3 4 5 6 7 8]
b=a.reshape(2,4) #视图变维 :变维2行4列的二维数组
print(b) # [[1 2 3 4]
# [5 6 7 8]]
c=b.reshape(2,2,2) #视图变维 :变维2页2行2列的三维数组
print(c)
d=c.ravel() #视图变维 :变为一维数组
print(d)
2.复制变维
(数据独立):flatten()
# 复制变维(数据独立):flatten()
import numpy as np
a=np.arange(1,9)
e=a.flatten()
print(e) # [1 2 3 4 5 6 7 8]
3.就地变维
(上边两种都是有返回值赋给新的数组,这个直接改变数组维度)
#就地变维 上边两种都是有返回值赋给新的数组,这个直接改变数组维度
a=np.arange(1,9)
a[0]=999
a.shape=(4,2)
print(a,a.shape)
"""
[[999 2]
[ 3 4]
[ 5 6]
[ 7 8]] (4, 2)
"""
# 将a设置为一维的
a.resize((8,))
print(a) # [999 2 3 4 5 6 7 8]
4.ndarry数组切片操作
数组对象切片的参数设置与列表切面参数类似
步长 + :默认切从首到尾
步长 - :默认切从尾到首
数组对象[起始位置:终止位置:步长,…]
默认位置步长:1
一维数组切片:
import numpy as np
a=np.arange(10)
print(a) #[0 1 2 3 4 5 6 7 8 9]
print(a[:3]) #[0 1 2]
print(a[3:6]) #[3 4 5]
print(a[6:]) #[6 7 8 9]
print(a[::-1]) #[9 8 7 6 5 4 3 2 1 0]
print(a[:-4:-1]) #[9 8 7]
print(a[-4:-7:-1]) #[6 5 4]
print(a[-7::-1]) #[3 2 1 0]
print(a[::3]) #[0 3 6 9]
多维数组切片:
#多维数组的切片操作
import numpy as np
a=np.arange(9)
a.resize(3,3)
print(a)
print(a[:2,:2]) #逗号前切行,逗号后切列 前两行,前两列 [[0 1] [2 3]]
print(a[::2,:]) # 1 3两行,所有列 [[0 1 2] [6 7 8]]
print(a[::2,::2]) # 1 3两行,1 3两列 [[0 2] [6 8]]
print(a[:,0]) #第一列 [0 3 6]
5. ndarray的掩码操作
# ndarray的掩码操作 基于bool数组的掩码
import numpy as np
a=np.arange(1,10)
mask=[True,False,True,False,True,False,True,False,True]
print(a[mask]) #[1 3 5 7 9]
# 输出100以内3的倍数
a=np.arange(100)
print(a[a%3==0])
# 输出100以内7和3的公倍数
mask=(a%3==0) & (a%7==0)
print(a[mask])
# 基于索引的掩码
names=np.array(['Apple','Mate30','XiaoMi','Vivo','Oppo'])
rank=[1,0,3,4,2]
print(names[rank]) #['Mate30' 'Apple' 'Vivo' 'Oppo' 'XiaoMi']
6.长度不等的数组组合
# 长度不等的数组组合
import numpy as np
a=np.array([1,2,3,4,5])
b=np.array([1,2,3,4])
# 填充b使其长度与a相同 pad_width=(0,1) 往头部补0个元素,尾部补1个元素, mode='constant' 以常量方式不全,constant_values=-1补-1
b=np.pad(b,pad_width=(0,1),mode='constant',constant_values=-1)
print(b) # [ 1 2 3 4 -1]
# 垂直方向完成组合操作,生成新数组
c=np.vstack((a,b))
print(c)
"""
[[ 1 2 3 4 5]
[ 1 2 3 4 -1]]
"""
# 简单的一维数组组合方案
a=np.arange(1,9)
b=np.arange(9,17)
# 把两个数组摞在一起组成两行
c=np.row_stack((a,b))
print(c)
"""
[[ 1 2 3 4 5 6 7 8]
[ 9 10 11 12 13 14 15 16]]
"""
# 把两个数组组合在一起成两列
d=np.column_stack((a,b))
print(d)
"""
[[ 1 9]
[ 2 10]
[ 3 11]
[ 4 12]
[ 5 13]
[ 6 14]
[ 7 15]
[ 8 16]]
"""
7.ndarray 类的其他属性
- shape 维度
- dtype 元素类型
- size 元素数量
- ndim 维数,len(shape)
- itemsize (一个)元素字节数
- nbytes 总字节数 = size * itemsize
- real 复数数组的实部数组
- imag 复数数组的虚部数组
- T 数组对象的转置视图
- flat 扁平迭代器
import numpy as np
a=np.array([[1+1j,2+4j,3+7j],
[4+2j,5+5j,6+8j],
[7+3j,8+6j,9+9j]])
print(a.shape) # (3, 3)
print(a.dtype) # complex128 64位实部 64位虚部
print(a.ndim) # 2 维数
print(a.size) # 9
print(a.itemsize) # 16 每个元素的字节数 128/8
print(a.nbytes) # 144 总共占144字节 9*16
print(a.real) # 实部
print(a.imag) # 虚部
print(a.T) # a的转置
print([x for x in a.flat]) # 扁平迭代器,将a衬平遍历
8.多维数组的组合与拆分
import numpy as np
# 垂直方向操作
a=np.arange(1,7).reshape(2,3)
b=np.arange(7,13).reshape(2,3)
# 垂直方向完成组合操作,生成新数组
c=np.vstack((a,b))
print(c)
# 垂直方向完成拆分操作,生成两个数组
d,e=np.vsplit(c,2)
print(d)
print(e)
print('----------')
# 水平方向操作
a=np.arange(1,7).reshape(2,3)
b=np.arange(7,13).reshape(2,3)
# 水平方向完成组合操作,生成新数组
c=np.hstack((a,b))
print(c)
# 水平方向完成拆分操作,生成两个数组
d,e=np.hsplit(c,2)
print(d)
print(e)
print('----------')
# 深度方向操作
a=np.arange(1,7).reshape(2,3)
b=np.arange(7,13).reshape(2,3)
# 深度方向(3维)完成组合操作,生成新数组
c=np.dstack((a,b))
print(c)
# 深度方向完成拆分操作,生成两个数组
d,e=np.dsplit(c,2)
print(d)
print(e)
print('----------')
# 通过axis作为关键字参数指定组合的方向,取值如下
# 若待组合的数组都是二维数组:
# 0 :垂直方向组合
# 1 :水平方向组合
# 若待组合的数组都是三维数组
# 0 :垂直方向组合
# 1 :水平方向组合
# 2 :深度方向组合
c=np.concatenate((a,b),axis=0)
print(c)
# 通过给出的数组与要拆分的份数,按照某个方向进行拆分
d,e=np.split(c,2,0)
print(d)
print(e)