NumPy用法总结

NumPy用法总结

快速了解NumPy

NumPy是一个开源的Python科学计算库,用于快速处理任意维度的数组。
NumPy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用NumPy比直接使用Python要简洁的多。
NumPy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器

优势

  1. 对于同样的数值计算任务,使用Numpy要比直接编写Python代码便捷地多
  2. NumPy中的数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构,且能够提升的性能是与数组中的元素成比例的
  3. Numpy的大部分代码都是用C语言写的,其底层算法在设计时就有着优异的性能,这使得NumPy比纯Python代码高效地多

NumPy的Ndarray对象

创建一维数组

# 一维数组
import numpy as np

# 创建数组的多种形式

# 1. 直接传入列表的形式进行创建
list1 = [1,2,3,4,5]
oneArray = np.array(list1)
print(type(oneArray))
print(oneArray)

# 2.传入range()生成序列
t2 = np.array(range(10))
print(t2)
print(type(t2))

# 3. 使用numpy自带的np.arange()生成数组
t3 = np.arange(0,10,2)
print(t3)
print(type(t3))

运行结果:
<class 'numpy.ndarray'>
[1 2 3 4 5]

[0 1 2 3 4 5 6 7 8 9]
<class 'numpy.ndarray'>

[0 2 4 6 8]
<class 'numpy.ndarray'>


创建二维数组

# 创建二维数组
import numpy as np
list2 = [[1,2],[3,4],[5,6]]

twoArray = np.array(list2)
print(twoArray)

运行结果:
[[1 2]
[3 4]
[5 6]]


常用属性

# 常用属性
import numpy as np

list2 = [[1,2],[3,4],[5,6]]

twoArray = np.array(list2)
print(twoArray)

# 获取数组的维度(注意:与函数的参数很像)
print(twoArray.ndim)

# 形状(行,列)
print(twoArray.shape)

# 有多少个元素
print(twoArray.size)

运行结果:
[[1 2]
[3 4]
[5 6]]

2

(3, 2)

6


调整数组的形状

import numpy as np

four = np.array([[1,2,3],[4,5,6]])

print(four,four.shape,id(four))
# 修改的是原有的
# four.shape = (3,2)
# print(four)
# 修改返回一个新的数组
# five = four.reshape(3,2)
# print(four,id(five))
# print(four)

# 将多维数组变成一维数组
# 默认情况下 'C'以行为主的顺序展开,'F'(Fortran风格)意味着以列的顺序展开
five = four.reshape((6,),order="F")
six = four.flatten(order='C')
print(five)
print(six)

运行结果:
[[1 2 3]
[4 5 6]] (2, 3) 2183058601424

[1 4 2 5 3 6]
[1 2 3 4 5 6]


# 维度的转换
t = np.arange(24)
print(t)
print(t.shape)
# 转化为二维
t1 =t.reshape((4,6))
print(t1)
print(t1.shape)
# 转化为三维
t2 = t.reshape((2,3,4))
print(t2)
print(t2.shape)

运行结果:
[ 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,)

[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
(4, 6)

[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
(2, 3, 4)


将数组转为list

# 将数组转化为列表
a = np.array([9,12,88,14,25])
list_a = a.tolist()
print(list_a)
print(type(list_a))

运行结果:
[9, 12, 88, 14, 25]
<class 'list'>


数组的计算

数组和数的计算

# 数组的操作
t1 = np.arange(24).reshape((6,4))
t2 = np.arange(100,124).reshape((6,4))
print(t1)
print(t2)
print(t1+t2)
print(t1*t2)

运行结果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]

[[100 101 102 103]
[104 105 106 107]
[108 109 110 111]
[112 113 114 115]
[116 117 118 119]
[120 121 122 123]]

[[100 102 104 106]
[108 110 112 114]
[116 118 120 122]
[124 126 128 130]
[132 134 136 138]
[140 142 144 146]]

[[ 0 101 204 309]
[ 416 525 636 749]
[ 864 981 1100 1221]
[1344 1469 1596 1725]
[1856 1989 2124 2261]
[2400 2541 2684 2829]]


数组与数组之间的操作

# 不同形状的多维数组不可以进行计算
t1 = np.arange(24).reshape((4,6))
t2 = np.arange(18).reshape((3,6))
print(t1)
print(t2)
# print(t1-t2)
# 行数或列数相同的一维数组和多维数组也可以进行计算,直适合一维数组和多维数组的情况
# 行形状相同
t1 = np.arange(24).reshape((4,6))
t2 = np.arange(0,6)
print(t1)
print(t2)
print(t1-t2)

运行结果:
[[ 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 4 5]

[[ 0 0 0 0 0 0]
[ 6 6 6 6 6 6]
[12 12 12 12 12 12]
[18 18 18 18 18 18]]


# 列形状相同
t1 = np.arange(24).reshape((4,6))
t2 = np.arange(4).reshape((4,1))
print(t1)
print(t2)
print(t1+t2)

运行结果:
[[ 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]]

[[ 0 1 2 3 4 5]
[ 7 8 9 10 11 12]
[14 15 16 17 18 19]
[21 22 23 24 25 26]]


数组中的轴

# 轴的理解
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a)

print(np.sum(a,axis=0))
print(np.sum(a,axis=1))

print(np.sum(a))

[[1 2 3]
[4 5 6]]

[5 7 9]

[ 6 15]

21


# 轴的理解之三维数组
a =  np.arange(27).reshape((3,3,3))
print('原三维数组')
print(a)
print('-----------')

b = np.sum(a,axis=0)
print('0轴')
print(b)
print('-----------')

c = np.sum(a,axis=1)
print('1轴')
print(c)
print('-----------')

d= np.sum(a,axis=2)
print('2轴')
print(d)
print('-----------')

运行结果:
原三维数组
[[[ 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]]]

0轴
[[27 30 33]
[36 39 42]
[45 48 51]]

1轴
[[ 9 12 15]
[36 39 42]
[63 66 69]]

2轴
[[ 3 12 21]
[30 39 48]
[57 66 75]]


数组中的索引和切片

# 数组的索引和切片
# 一维数组
a = np.arange(10)
print(a)
# 冒号分隔切片参数 start:stop:step 来进行切片操作
print(a[2:7:2]) # 从索引 2 开始索引 到 7 停止(不包括7) 间隔为 2

# 如果只放置一个参数 如[2]  将返回与该索引相对应的单个元素
print(a[2],a)

# 如果为 [2:],表示从该索引(包括该索引)开始以后的所有项将都被提取
print(a[2:])

运行结果:
[0 1 2 3 4 5 6 7 8 9]

[2 4 6]

2 [0 1 2 3 4 5 6 7 8 9]

[2 3 4 5 6 7 8 9]


# 数组的索引之多维数组
t1 = np.arange(24).reshape(4,6)
print('原数组')
print(t1)
print('*'*20)
print('取一行')
print(t1[1]) # 取一行(一行代表一条数据,索引也是从0开始的)
print('取一行')
print(t1[1,:]) # 取一行 (根据行和列进行索取)
print("*"*20)
print('取连续的多行')
print(t1[1:])     #取连续的多行 和所有的列   取第二行以及以后的行数
print('取连续的多行')
print(t1[1:3,:])  #取连续的多行   取第二行,第三行,不取第四行
print('取不连续的多行')
print(t1[[1,3],:]) # 取不连续的多行
print("*"*20)
print('原数组')
print(t1)
print('取出一列')
print(t1[:,1]) # 取出一列  索引为1 即第二列
print('取出连续的多列')
print(t1[:,1:])# 取出连续的多列 
print('取出不连续的多列')
print(t1[:,[0,2,3]]) # 取不连续的多列
print('取出某一个特定的值')
print(t1[3,4]) #取某一个特定的值,第四行第五列
print('取多个不连续的值')
print(t1[[0,1,1],[0,1,3]])

数组中的数值修改

t = np.arange(24).reshape(4,6)
print(t)
print()

# 修改某一行的值
t[1,:]=0
print(t)
print()

# 修改连续多行
t[1:3,:]=0
print(t)
print()

# 修改连续多列
t[:,1:4]=0
print(t)
print()

# 修改多个不相邻的点
t[[0,3],[5,5]]=0
print(t)
print()

运行结果:
[[ 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 4 5]
[ 0 0 0 0 0 0]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]

[[ 0 1 2 3 4 5]
[ 0 0 0 0 0 0]
[ 0 0 0 0 0 0]
[18 19 20 21 22 23]]

[[ 0 0 0 0 4 5]
[ 0 0 0 0 0 0]
[ 0 0 0 0 0 0]
[18 0 0 0 22 23]]

[[ 0 0 0 0 4 0]
[ 0 0 0 0 0 0]
[ 0 0 0 0 0 0]
[18 0 0 0 22 0]]


数组的添加、删除、去重

# 数组的添加
'''
arr: 输入的数组
values: 要向 arr 中添加的值 ,需要和 arr 形状相同(除了要添加的轴)
axis : 默认为None 不输入时默认以一维数组的形式添加 
'''
a = np.array([[1,2,3],[4,5,6]])
print('第一个数组:')
print(a)
print('
')

# 该添加方法会先把二维数组转化为一维数组,然后进行添加,结果是一维数组
print('向数组中添加元素:')
print(np.append(a,[7,8,9]))
print('
')

print('沿0轴添加元素:')
print(np.append(a,[[7,8,9]],axis=0))
print('
')

print('沿1轴添加元素')
print(np.append(a,[[5,5,5],[7,8,9]],axis=1))
print('
')

运行结果:
第一个数组:
[[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 5 5 5]
[4 5 6 7 8 9]]


# 数组的添加 insert 方法
import numpy as np

a = np.array([[1,2],[3,4],[5,6]])
print('第一个数组:')
print(a)
print('
')

print('未传递 axis 参数。在插入参数 之前输入数组会被展开')
# 插到索引位置之前
print(np.insert(a,3,[11,12]))
print('
')

print('传递了 axis 参数。会广播数组来匹配输入数组')
print('沿 0 轴广播:')
print(np.insert(a,1,[11],axis=0))
print('
')

print('沿1轴广播:')
print(np.insert(a,1,[11,12,13],axis=1))

运行结果:
第一个数组:
[[1 2]
[3 4]
[5 6]]

未传递 axis 参数。在插入参数 之前输入数组会被展开
[ 1 2 3 11 12 4 5 6]

传递了 axis 参数。会广播数组来匹配输入数组
沿 0 轴广播:
[[ 1 2]
[11 11]
[ 3 4]
[ 5 6]]

沿1轴广播:
[[ 1 11 2]
[ 3 12 4]
[ 5 13 6]]


# 数组删除 delete
'''
参数说明:
arr: 输入的数组
obj: 可以被切片,整数或者整数数组 ,表明要从输入数组删除的子数组
axis : 沿着它删除给定子数组的轴 ,如果未提供 ,则输入数组会被展开
'''
a = np.arange(12).reshape(3,4)

print('第一个数组:')
print(a)
print('
')

print('未传递 Axis 参数。 在删除之前输入数组会被展开')
# 根据索引进行删除
print(np.delete(a,5))
print('
')

print('删除每一行中的第二列:')
print(np.delete(a,1,axis=1))
print('
')

print('删除每一列中的第一行:')
print(np.delete(a,0,axis=0))
print('
')

运行结果:
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

未传递 Axis 参数。 在删除之前输入数组会被展开
[ 0 1 2 3 4 6 7 8 9 10 11]

删除每一行中的第二列:
[[ 0 2 3]
[ 4 6 7]
[ 8 10 11]]

删除每一列中的第一行:
[[ 4 5 6 7]
[ 8 9 10 11]]


# 数组去重
'''
参数设置
arr: 输入数组 ,如果不是一维数组 则会展开
return_index: 如果为true ,返回新列表元素在旧的列表中的位置(下标),并以列表形式储存
return_inverse: 如果为 true ,返回旧列表元素在新列表中的位置,并以列表形式储存
return_counts : 如果为 true ,返回去重数组中的元素在原数组出现次数 
'''
a = np.array([5,2,6,2,7,5,6,8,2,9])

print('第一个数组:')
print(a)
print('
')

print('第一个数组的去重值:')
u = np.unique(a)
print(u)
print('
')

print('新列表元素在旧的列表中的位置(下标):')
u,indices = np.unique(a,return_index=True)
print(indices)
print('
')

print('旧列表元素对应新列表的位置(下标)')
u,indices = np.unique(a,return_inverse=True)
print(u)
print(indices)
print(a)
print('
')

print('返回去重元素的重复数量:')
u,indices = np.unique(a,return_counts=True)
print(u)
print(indices)

运行结果:
第一个数组:
[5 2 6 2 7 5 6 8 2 9]

第一个数组的去重值:
[2 5 6 7 8 9]

新列表元素在旧的列表中的位置(下标):
[1 0 2 4 7 9]

旧列表元素对应新列表的位置(下标)
[2 5 6 7 8 9]
[1 0 2 0 3 1 2 4 0 5]
[5 2 6 2 7 5 6 8 2 9]

返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]


numpy的计算

# numpy 的 计算
import numpy as np
score = np.array([[80,88],[82,83],[75,81]])

print('原数组:
',score,'
')

# 1. 获取所有数据最大值
result = np.max(score)
print('整个数组的最大值',result,'
')

# 获取某一个轴上的数据最大值
result = np.max(score,axis=0)
print('获取0轴上的数据最大值',result,'
')

# 获取最小值
result = np.min(score)
print("获取整个数组的最小值:",result,'
')

# 获取某一个轴上的数据最小值
result = np.min(score,axis=1)
print('1轴上的最小值:',result,'
')

# 数据的比较 
result = np.maximum([-2,-1,0,1,2],0) # 第一个参数中的每一个数与第二个参数比较返回大的
print('数据比较 返回大的',result,'
')

result = np.minimum([-2,-1,0,1,2],0) # 第一个参数中的每一个数与第二个参数比较返回小的
print('数据比较 返回小的',result,'
')

result = np.maximum([-2,-1,0,1,2],[1,-2,3,4,5]) # 接受两个参数,可以大小一致 第二个参数只是
# 一个值时 利用维度的广播机制
print('数据比较 返回大的',result,'
')

# 求取平均值
result = np.mean(score) #获取所有数据的平均值
print('获取所有数据的平均值',result,'
')
result = np.mean(score,axis=0)
print('获取某一行或某一列的平均值',np.mean(score,axis=0),np.mean(score,axis=1),'
')

# 返回给定axis上的累计和
#axis=0,代表以行方式扫描,第一次扫描第一行,第二次扫描第二行,以此类推。
#第一行扫描时,没有前几行可累加,所以数值不变。扫描到第二行,累加前几行,以此类推。
arr = np.array([[1,2,3],[4,5,6]])
print('数组:
',arr,'
')
print(arr.cumsum(0),'
')
print(arr.cumsum(1),'
')

#  argmin 求最小值索引
result = np.argmin(score,axis=0)
print(result,'
')
#  求每列的标准差
result = np.std(score,axis=0)
print('每列的标准差',result,'
')

# 极值
print('最大值和最小值的差',np.ptp(score,axis=None))

# 扩展: 方差 var , 协方差 cov ,计算平均值 average, 计算中位数 median

数组的拼接

# 数组的拼接
#  1. 根据轴连接的数组序列
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])

# 要求 a,b 两个数组的维度相同
print('沿0轴连接两个数组:')
print(np.concatenate((a,b),axis=0))
print('
')
print('沿 1 轴 连接两个数组:')
print(np.concatenate((a,b),axis=1),'
')

# 根据轴进行堆叠
print(a)
print(b)
print('沿 0 轴 连接两个数组:')
print(np.stack((a,b),axis=0))
print('
')
print('沿 1 轴 连接两个数组:')
print(np.stack((a,b),axis=1))

# 矩阵 垂直拼接
v1 = [[0,1,2,3,4,5],[6,7,8,9,10,11]]
v2 = [[12,13,14,15,16,17],[18,19,20,21,22,23]]

result = np.vstack((v1,v2))
print(result)

# 矩阵水平拼接
print(np.hstack((v1,v2)))

数组的分割

# 将一个数组分割成多个子数组
'''
参数说明:
arr: 被分割的数组
indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分位置(左开右闭)
axis: 沿着哪个维度进行切分,默认是0 ,横向切分。为1时,纵向切分
'''
arr = np.arange(9).reshape(3,3)
print('将数组分成三个大小相等的子数组:')
b = np.split(arr,3)
print(b)

# 2. numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组
# floor() 返回数字的下舍整数
harr = np.floor(10 * np.random.random((2,6)))
print('原 array ')
print(harr)
print('拆分后:')
print(np.hsplit(harr,3))

#  numpy.vsplit:沿着垂直轴分割
a = np.arange(16).reshape(4,4)
print('第一个数组:')
print(a)
print('
')

print('沿着垂直轴分割:')
b = np.vsplit(a,2)
print(b)

运行结果:
将数组分成三个大小相等的子数组:
[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
原 array
[[4. 2. 2. 2. 8. 6.]
[7. 3. 8. 7. 6. 0.]]
拆分后:
[array([[4., 2.],
[7., 3.]]), array([[2., 2.],
[8., 7.]]), array([[8., 6.],
[6., 0.]])]
第一个数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]

竖直分割:
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]


数组中的nan 和 inf

#  nan(缺失的数据) inf(无穷大)
#  创建一个nan 和 inf

a = np.nan # 空值(缺失数据)
b = np.inf # 无穷大
print(a,type(a))
print(b,type(b))

# 判断数组中为nan的个数 (注意:float类型的数据才能赋值 nan)
t = np.arange(24,dtype=float).reshape(4,6)
print(t)
# 可以使用 np.count_nonzero()来判断非零的个数
print(np.count_nonzero(t))
# 将三行四列的数改成 nan
t[3,4] = np.nan
print(t)
# 并且 np.nan != np.nan 结果是True  np.nan == np.nan False 结合这个性质进行判断
print(np.count_nonzero(t != t))
print('isnan:',np.isnan(t))

# 注意:nan 和任何数计算都为 nan
print(np.sum(t,axis=0))

# 将 nan 替换成 0 
t[np.isnan(t)] = 0
print(t)
print('*' * 30)

# 练习 :处理数组中的nan
t = np.arange(24).reshape(4,6).astype('float')
# 将数组中的一部分替换成 nan
t[1,3:] = np.nan
print(t)
# 遍历每一列 ,然后判断每一列 是否有nan
# t.shape[1] s数组中的总列数
print(t.shape[1])
for i in range(t.shape[1]):
    temp_col = t[:,i]
    nan_num = np.count_nonzero(temp_col != temp_col)
    if nan_num != 0:
        # 取出这一列中不为nan的元素
        temp_col_not_nan = temp_col[temp_col==temp_col]
        # 将nan替换成这一列的平均值   
        # np.isnan(temp_col) : 参数:数组 返回nan的索引
        temp_col[np.isnan(temp_col)] = np.mean(temp_col_not_nan)
print(t)

运行结果:
nan <class 'float'>
inf <class 'float'>
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. 22. 23.]]
23
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. nan 23.]]
1
isnan: [[False False False False False False]
[False False False False False False]
[False False False False False False]
[False False False False True False]]
[36. 40. 44. 48. nan 56.]
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 9. 10. 11.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. 0. 23.]]


[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. nan nan nan]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. 22. 23.]]
6
[[ 0. 1. 2. 3. 4. 5.]
[ 6. 7. 8. 13. 14. 15.]
[12. 13. 14. 15. 16. 17.]
[18. 19. 20. 21. 22. 23.]]


二维数组的转置

# 二维数组的转置
a = np.arange(12).reshape(3,4)

print('原数组:')
print(a)
print('
')

print('对换数组:')
print(np.transpose(a))

# 与 transpose 一致
print('转置数组:')
print(a.T)
print('
')

# 函数用于交换数组的两个轴
t1 = np.arange(24).reshape(4,6)
re = t1.swapaxes(1,0)
print('原数组:')
print(t1)
print('
')

print('调用 swapaxes 函数后的数组:')
print(re)
原文地址:https://www.cnblogs.com/weixiao1717/p/14318096.html