Numpy常用方法
Numpy常用方法
课程地址:Python数据分析与展示
前言
一维数据
列表:数据类型可以不同 [3.14, ‘pi’, 3.1415, [3.14,3], ‘3.14’]
数组:数据类型必须相同 [3.1412, 3.1413, 3.1414, 3.1415]
列表(有序)和集合(无序)类型
[3.1311, 3.1314, 3.1315] {3.1311, 3.1314, 3.1315}
多维数据
3.1413 | 3.1413 |
---|---|
3.1414 | 3.1415 |
列表嵌套
[[3.1413, 3.1413], [3.1414, 3.1415]]
高维数据
高维数据仅利用最基本的二元关系展示数据间的复杂结构。(键值对)
字典
1 | dict={ |
json
1 | { |
还有XML,Yaml等。
Numpy的ndarray对象
import numpy as np
引入模板
数组对象可以去掉元素间运算需要的循环,使移位向量更像单个数据,同时提升运算速度(底层C实现)。
ndarray对象
上述np.array()
生成一个ndarray
数组,在程序中的别名为array
。ndarray
在控制台输出为[]形式,元素由空格分割。
1 | 0,1,2,3,4],[5,6,7,8,9]]) a=np.array([[ |
轴(axis):保存数据的维度
秩(rank):轴的数量
ndarray对象的属性
以上个例子为例
1 | 0,1,2,3,4],[5,6,7,8,9]]) a=np.array([[ |
ndarray支持的数据类型
因为对元素类型精确定义有助于合理使用储存空间,所以尽量避免使用非同质元素类型。当元素不同时,会出现
1 | x=np.array([[0,1,2,3,4],[5,6,7,8]]) |
ndarray数组的创建
- 从python的列表、元祖等类型创建ndarray数组
1 | 0,1,2,3]) #从列表类型创建 x=np.array([ |
- 从Numpy函数创建ndarray数组
1 | 10) np.arange( |
1 | x.shape |
1 | 1,10,4) np.linspace( |
为了方便运算,默认创建的数组元素是浮点数。
ndarray数组的维度变换
1 | 2,3,4),dtype=np.int32) a=np.ones(( |
ndarray数组元素类型变化
方法 | 说明 |
---|---|
.astype(new_type) |
不改变数组维度,返回数组元素类型改变后的数组 |
1 | 2,3,4),dtype=np.int32) a=np.ones(( |
ndarray数组向列表的转换
方法 | 说明 |
---|---|
.tolist() |
不改变数组维度和元素类型,返回列表(运算效率可能下降) |
1 | 2,3,4),25,dtype=np.int32) a=np.full(( |
ndarray数组的操作
ndarray索引
一维数组的索引
1
2
3
4
5
6
7# 一维数组的索引和列表相似
9,8,7,6,5]) a=np.array([
2] a[
7
1:4:2] a[
array([8, 6])
>>>多维数组的索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1524).reshape((2,3,4)) a=np.arange(
a
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]]])
1,2,3] a[
23
0,1,2] a[
6
1,-2,-3] a[-
17
ndarray切片
一维数组的切片
和列表的切片类似
多维数组的切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2524).reshape((2,3,4)) a=np.arange(
a
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]]])
1,-3] a[:,
array([ 5, 17])
1:3,:] a[:,
array([[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[16, 17, 18, 19],
[20, 21, 22, 23]]])
2] #a[0:10:2]表示0-9步长为2的切片 a[:,:,::
array([[[ 0, 2],
[ 4, 6],
[ 8, 10]],
[[12, 14],
[16, 18],
[20, 22]]])
ndarray数组的运算
数组与标量的运算
1 | 24).reshape((2,3,4)) a=np.arange( |
数组与标量之间的运算作用于数组的每一个元素
数组元素运算的函数(一元函数)
元素级运算,即对数组每个元素进行运算。注意数组本身是否改变,大多数都输返回新数组,原数组不改变。
1 | 24).reshape((2,3,4)) a=np.arange( |
数组之间运算的函数(二元函数)
1 | 24).reshape((2,3,4)) a=np.arange( |
Numpy的文件存储
CSV文件介绍
CSV(Comma-Separated Value,逗号分隔值)。CSV是一种常见的文件格式,用来存储批量数据。
- 一个表格
城市 | 环比 | 同比 | 定基 |
---|---|---|---|
北京 | 101.5 | 120.7 | 121.4 |
上海 | 101.2 | 127.3 | 127.8 |
广州 | 101.3 | 119.4 | 120.8 |
深圳 | 102.0 | 140.9 | 145.5 |
沈阳 | 100.1 | 101.4 | 101.6 |
- 与之对应的CSV文件
1 | 城市,环比,同比,定基 |
CSV文件读写函数
np.savetxt()
np.loadtxt()
只能有效存取一维和二维数组。
文件写入函数
np.savetxt()
1
np.savetxt(frame,array,fmt='%.18e',delimiter=None)
frame
:文件,字符串或产生器,可以是.gz或.bz2的压缩文件。array
:存入文件的数组fmt
:写入文件的格式,例如%d,%.2f,%.18edelimiter
:分隔字符串,默认是任何空格因为CSV文件格式以
,
分隔,所以delimiter=','
1
2
3import numpy as np
a=np.arange(100).reshape(5,20)
np.savetxt("a.csv",a,fmt='%d',delimiter=',')
文件读取函数
np.loadtxt()
1
np.loadtxt(frame,dtype=np.float,delimiter=None,unpack=False)
frame
:文件,字符串或产生器,可以是.gz或.bz2的压缩文件。dtype
:数据类型,可选delimiter
:分隔字符串,默认是任何空格unpack
:如果为Ture,解包,读入属性将分别写入不同的变量(python的read()函数读取文件的数据都是字符格式,需要进一步int()转换)
1
2
3
4a=np.arange(100).reshape(5,20)
np.savetxt("a.csv",a,fmt='%.1f',delimiter=',')
b=np.loadtxt("a.csv",delimiter=',')
print("读取到的a的值为:\n",b)
多维文件读取函数
文件写入函数
ndarray.tofile()
1
ndarray.tofile(frame,sep='',format='%s')
frame
;文件,字符串sep
:数据风格字符串,如果是空串,写入文件为二进制format
:写入数据的格式1
2
3import numpy as np
a=np.arange(100).reshape(2,5,10)
a.tofile("b.dat",sep=',',format='%d')b.dat
不包含任何维度信息。如果sep=','
未设置,b.dat
将是一个二进制文件。文件读取函数
np.fromfile()
1
np.fromfile(frame,dtype=float,count=-1,sep='')
frame
:文件,字符串dtype
:读取的数据类型count
:读入元素个数,-1表示读入整个文件sep
:数据分割字符串,如果是空串,写入文件为二进制1
2
3
4a=np.arange(100).reshape(2,5,10)
a.tofile("b.dat",sep=',',format='%d')
c = np.fromfile("b.dat",dtype=np.int,sep=',').reshape(5,10,2)
print(c)
多维文件的元数据处理
利用上述ndarray.tofile()
和np.fromfile()
函数时,我们看到文件存储的数据只有纯内容,缺乏维度信息。对于这类元数据,一般的处理方法是另建一个配置文件写明元数据信息。同时,Numpy提供了一个便捷的文件存储办法。
np.save
(或者np.savez
)1
2np.save(fname,array)
np.savez(frame,array)frame
:文件名,以.npy
为扩展名,压缩扩展名为.npz
array
:数组变量np.load
1
np.load(fname)
frame
:文件名,以.npy
为扩展名,压缩扩展名为.npz
1 | import numpy as np |
文件写入
文件读取
Numpy的随机函数子库
从零随机生成数据的函数
np.rand(d0,d1,...,dn)
从[0-1]随机生成符合维度参数的数组,满足(0-1)均匀分布1
2
3
4
5
6
7
82,3,4) np.random.rand(
array([[[0.20259939, 0.00962878, 0.56450046, 0.71235863],
[0.01549391, 0.49664883, 0.16570365, 0.11222922],
[0.93839936, 0.65121818, 0.35750042, 0.84551314]],
[[0.56703213, 0.45897042, 0.21583654, 0.6436646 ],
[0.73612895, 0.80503486, 0.93915543, 0.33008223],
[0.86046784, 0.36052457, 0.33578919, 0.16510733]]])np.randn(d0,d1,...,dn)
随机生成符合维度参数的数组,满足标准正态分布1
2
3
4
5
6
7
82,3,4) np.random.randn(
array([[[ 1.55199709, 1.41594185, -0.1622146 , 0.48272732],
[-0.70775139, 2.38247535, 1.52048942, -0.95379195],
[ 0.72480865, 0.19713822, 0.5858833 , -0.3099266 ]],
[[ 1.06940348, 0.47979532, 0.98184603, 0.64469512],
[-3.09162702, -0.78907275, 0.32596385, 1.5061127 ],
[ 0.28365334, 0.08427444, 0.67566961, 2.54296885]]])np.randint(low,high,shape)
从[100,200)随机生成整数1
2
3
4100,200,(3,4)) np.random.randint(
array([[156, 100, 152, 180],
[104, 168, 165, 167],
[192, 137, 194, 163]])np.seed(num)
按照种子生成随机数,通过设定seed,可以产生同一个数组1
2
3
4
5
6
7
8
9
1010) np.random.seed(
100,200,(3,4)) np.random.randint(
array([[109, 115, 164, 128],
[189, 193, 129, 108],
[173, 100, 140, 136]])
10) #再次设置seed为10,产生一样的数组 np.random.seed(
100,200,(3,4)) np.random.randint(
array([[109, 115, 164, 128],
[189, 193, 129, 108],
[173, 100, 140, 136]])
从已有数组抽取或重排的函数
np.random.shuffle(array)
将数组a的第一层随机排列,内层跟随第一层进行改变1
2
3
4
5
6
7
8100,200,(2,3)) a=np.random.randint(
a
array([[116, 111, 154],
[188, 162, 133]])
np.random.shuffle(a)
a
array([[188, 162, 133],
[116, 111, 154]])np.random.permutation(array)
相当于shuffle()带返回值的版本,不改变原数组1
2
3
4
5
6
7
8
9
10100,200,(2,3)) a=np.random.randint(
a
array([[178, 149, 151],
[154, 177, 169]])
np.randim.permutation(a)
array([[154, 177, 169],
[178, 149, 151]])
a
array([[178, 149, 151],
[154, 177, 169]])np.random.choice(array,shape,replace,p)
以概率p抽取元素,返回新数组1
2
3
4
5
6
7
8
9
10
11
12
13
14
15100,200,8) a=np.random.randint(
a
array([112, 165, 131, 157, 136, 127, 118, 193])
3,2)) np.random.choice(a,(
array([[112, 193],
[127, 112],
[193, 127]])
3,2),replace=False) np.random.choice(a,(
array([[193, 127],
[118, 157],
[165, 112]])
3,2),p=a/np.sum(a)) # 元素越大,抽取率越高 np.random.choice(a,(
array([[193, 157],
[112, 193],
[131, 136]])
按照数学分布生成数据的函数
np.random.uniform.uniform(low,high,size)
产生具有均匀分布的数组1
2
3
40,10,(3,4)) #从(0,10)等概率抽取 np.random.uniform(
array([[4.90554679, 0.29179556, 5.9486095 , 2.05845476],
[2.02802974, 8.44125875, 0.61566377, 4.99230689],
[2.48466979, 3.27144028, 0.02916088, 2.95442135]])np.random.normal(loc,scale,size)
产生具有正态分布的数组1
2
3
410,5,(3,4)) #均值是10,方差是5 np.random.normal(
array([[12.87109037, 14.66311162, 10.45457509, 2.63002415],
[10.55279029, 11.26839975, 11.32440894, 13.62386089],
[ 7.32322561, 9.04697536, 7.64661696, 8.1869246 ]])np.random.poisson(lam,size)
产生具有泊松分布的数组
Numpy的统计函数
1 | 18).reshape(2,3,3) a=np.arange( |
np.sum(array,axis=None)
1
2sum(a) np.
153np.mean(array,axis=None)
1
2
3
4
5
6
7
8
9
100) # 最外层 np.mean(a,axis=
array([[ 4.5, 5.5, 6.5], # 4.5=(0+9)/2
[ 7.5, 8.5, 9.5], # 8.5=(4+13)/2
[10.5, 11.5, 12.5]]) # 12.5=(8+17)/2
1) # 第二层 np.mean(a,axis=
array([[ 3., 4., 5.], # 3.=(0+6)/2
[12., 13., 14.]]) # 13.=(10+16)/2
2) # 第三层 np.mean(a,axis=
array([[ 1., 4., 7.], # 1.=(0+2)/2
[10., 13., 16.]]) # 13.=(12+14)/2
np.average(array,axis=None,weights=None)
1
2
3
4
5
6
7
8
9
100,weights=[1,2]) # 最外层 np.average(a,axis=
array([[ 6., 7., 8.], # 6.=(0*1+9*2)/(1+2)
[ 9., 10., 11.], # 10.=(4*1+13*2)/(1+2)
[12., 13., 14.]]) # 14.=(8*1+17*2)/(1+2)
1,weights=[1,2,3]) # 第二层 np.average(a,axis=
array([[ 4., 5., 6.], # 4.=(0*1+3*2+6*3)/(1+2+3)
[13., 14., 15.]]) # 14.=(10*1+13*2+16*3)/(1+2+3)
2,weights=[1,2,3]) # 第三层 np.average(a,axis=
array([[ 1.33333333, 4.33333333, 7.33333333], # 1.33333=(0*1+2*2+2*3)/(1+2+3)
[10.33333333, 13.33333333, 16.33333333]]) # 13.33333=(12*1+13*2+14*3)/(1+2+3)
np.std(array,axis=None)
1
2# a的标准差 np.std(a)
5.188127472091127np.var(a,axis=None)
1
2# a的方差 np.var(a)
26.916666666666668
1 | 18).reshape(2,3,3) a=np.arange( |
np.max(array)
1
2max(a) # 取得数组的最大值 np.
17np.argmax(array)
1
2# 将数组压缩为一维数组,找到最大值,返回其在一维数组中对应的下标 np.argmax(a)
17np.unravel_index(index,shape)
1
2np.unravel_index(np.argmax(a),a.shape)
(1, 2, 2) # 将一维下标index转换为,对应a.shape形状下的多维下标np.ptp(array)
1
2# 取得数组a中最大值和最小值的差 np.ptp(a)
17np.median(array)
1
2# 将数组a压缩为一维数组,重排列,返回一维数组的中位数 np.median(a)
8.5
Numpy的梯度函数
函数 | 说明 |
---|---|
np.gradient(array) |
计算数组array中元素的梯度,当f为多维时,返回每个维度梯度 |
梯度:连续值之间的变化率,即斜率
例如:XY坐标轴连续三个X坐标对应的Y轴值:a,b,c,其中,b的梯度为:(c-a)/2
多用于图像和音频的处理
一维梯度
1 | 0,20,(5)) a=np.random.randint( |
多维梯度
1 | 0,50,(3,5)) a=np.random.randint( |
图像变换
图像是一个由像素组成的二维矩阵,每个元素是一个RGB值。
用numpy打开后,图像是一个三维数组,维度分别是高度、宽度和像素RGB值。
RGB(255,255,255)可以用来改改改。
PIL库
安装pip install pillow
引入from PIL import Image
Image代表图像的对象。
1 | from PIL import Image |
原图
1 | im=np.array(Image.open("1.jpg")) |
色彩反转
1 | im=np.array(Image.open("1.jpg").convert('L')) # 取灰度值 |
灰度值
1 | im = np.array(Image.open("1.jpg").convert('L')) |
区间变化1
1 | change2_im = 255*(im*255)**2 # 进行第二个乱七八糟的区间变化 |
区间变化2
手绘图像
手绘风格图片特点:
- 黑白灰
- 边界线条较重
- 相同或相近色彩趋于白色
- 略有光源效果
1 | from PIL import Image |
手绘