logo头像

life is beautiful like sunshine!

numpy学习4:NumPy基本操作

一、数组与标量、数组之间的运算

数组不用循环即可对每个元素执行批量的算术运算操作,这个过程叫做矢量化,即用数组表达式代替循环的做法

矢量化数组运算性能比纯Python方式快上一两个数据级。

大小相等的两个数组之间的任何算术运算都会将其运算应用到元素级上的操作。

元素级操作:在NumPy中,大小相等的数组之间的运算,为元素级运算,即只用于位置相同的元素之间,所得的运算结果组成一个新的数组,运算结果的位置跟操作数位置相同。

1.1、数组与标量之间的运算

数组与标量之间的运算的意思是:数组和元素的运算,例如,在一个矩阵的基础上加上一个数,得到另外一个新的矩阵。

a = np.arange(9).reshape(3,3)
print("运算前:")
print(a)
print("加法:")
print(a+2)
print("减法:")
print(a-2)
print("乘法:")
print(a*2)
print("除法:")
print(a/2)

输出:

运算前:
[[0 1 2]
 [3 4 5]
 [6 7 8]]
加法:
[[ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]]
减法:
[[-2 -1  0]
 [ 1  2  3]
 [ 4  5  6]]
乘法:
[[ 0  2  4]
 [ 6  8 10]
 [12 14 16]]
除法:
[[0.  0.5 1. ]
 [1.5 2.  2.5]
 [3.  3.5 4. ]]

1.2、数组与数组之间的运算

'''
    Numpy算数运算
    用于执行算数运算的输入数组必须具有相同的行列或符合数组广播规则
'''
a = np.arange(9).reshape(3,3)
b = np.array([1,3,2])
print(a)
print(b)
print('**************************************')
#两个数组相加
print(np.add(a,b))
print(a+b)
print('**************************************')
#两个数组相减
print(a-b)
print(np.subtract(a,b))
print('**************************************')
#两个数组相乘
print(a*b)
print(np.multiply(a,b))
print('**************************************')
print(a/b)
print(np.divide(a,b))
print('**************************************')

#两个数组取幂
print(a**b)
print(np.power(a,b))
print('**************************************')
print()

print()
print('****************两个数组取余**********************')
#mod 两个数组取余
a = np.array([10,20,30])
b = np.array([3,5,7])
print(np.mod(a,b))
print(np.remainder(a,b))
print('**************************************')
print()

鉴于篇幅,输出结果就不给出了,结果也就是矩阵的基本运算的结果。

二、 数组的矩阵积(matrix product)

矩阵:多维数组即矩阵

矩阵积(matrix product):两个二维矩阵(行和列的矩阵)满足第一个矩阵的列数与第二个矩阵的行数相同,那么可以进行矩阵的乘法,即矩阵积,矩阵积不是元素级的运算。也称为点积、数量积。

1.png

2.png

即对应的每一行与每一列的元素对应相乘,得到新的矩阵。

print("*"*20)
arr1 = np.array([
    [10,6,20],
    [15,5,10],
    [12,67,20]
])
arr2 = np.array([
    [12.3,0.4],
    [24,2.4],
    [9.8,0.4]
])
#print(arr2)
print(arr1.dot(arr2))
print('*'*20)

三、 数组的索引与切片

每个矩阵都是有索引的,在行和列的方向上,都对应有索引,其实也相同于c语言或者java的数组索引类似,通过这样的方式,我们就可以很方便的获取部分值。

3.1、基本索引

类似于c语言或者java的数组操作

arr=np.array([
        [
            [1,2,3,4],
            [2,3,4,5],
            [3,4,5,6]
        ],
        [
            [10,20,30,40],
            [20,30,40,50],
            [30,40,50,60]
        ]
    ])
print(arr[1])
print(arr[1][1])
print(arr[1][1][2])

3.2、切片操作

通过在某一个维度上,更加细类度的获取相应的元素的过程。
通过使用::,来指定获取的元素的数量。

arr=np.array([
        [
            [1,2,3,4],
            [2,3,4,5],
            [3,4,5,6]
        ],
        [
            [10,20,30,40],
            [20,30,40,50],
            [30,40,50,60]
        ]
    ])

#取50
print(arr[1][1][3:])

1.png

注意:
1.png

  • 使用np.ix_()索引器
a = np.arange(9).reshape(3,3)
print(a)

#使用索引器 np.ix_()
num = a[np.ix_([0,1,2],[0,1])] #获取第0,1,2行的第0,1列的元素
print(num)
  • 花式索引

花式索引(Fancy indexing)指的是利用整数数组进行索引的方式。
1.png

2.png

  • 布尔索引

利用布尔类型的数组进行数据索引,最终返回的结果是对应索引数组中数据为True位置的值。

names = np.array(['james','lobe','tom'])
scores = np.array([
    [98,86,55,90],
    [70,86,90,99],
    [82,55,89,86]
])
classic = np.array(['语文','数学','英语','科学'])
print('lobe的成绩是:')
# print(names=='lobe')
print(scores[names=='lobe'])

print('lobe的数学成绩:')
# print(scores[names=='lobe',classic=='数学'])
print(scores[names=='lobe'].reshape(-1,)[classic=='数学'])

print('james和lobe的成绩是:')
print(scores[(names=='james')|(names=='lobe')])

print('非james和lobe的成绩')
print(scores[(names!='james')&(names!='lobe')])

输出:

lobe的成绩是:
[[70 86 90 99]]
lobe的数学成绩:
[86]
james和lobe的成绩是:
[[98 86 55 90]
 [70 86 90 99]]
非james和lobe的成绩
[[82 55 89 86]]

四、 数组的转置与轴对换

数组转置是指将shape进行重置操作,并将其值重置为原始shape元组的倒置,比如原始的shape值为:(2,3,4),那么转置后的新元组的shape的值为: (4,3,2)f

可以通过调用数组的transpose函数或者T属性进行数组转置操作

'''
    数组转置与轴对换
'''
arr = np.arange(100).reshape(10,10)
print(arr.shape)
# print(np.transpose(arr))
#print(arr.transpose())
print(arr.T)

五、 通用函数:快速的元素级数组成函数

ufunc:numpy模块中对ndarray中数据进行快速元素级运算的函数,也可以看做是简单的函数(接受一个或多个标量值,并产生一个或多个标量值)的矢量化包装器。

主要包括一元函数和二元函数

  • 一元函数

1.jpg

2.jpg

  • 二元函数

1.jpg

六、 聚合函数

聚合函数是对一组值(eg一个数组)进行操作,返回一个单一值作为结果的函数。当然聚合函数也可以指定对某个具体的轴进行数据聚合操作;常将的聚合操作有:平均值、最大值、最小值、方差等等

这些操作类似于数据库的聚合函数,其实操作也很相似,只是应用的场景不一样。

我们先回顾一下标准差和反差怎么计算:

  • 标准差
    标准差是与平均值的偏差的平方的平均值的平方根
    std = sqrt(mean((x-x.mean())**2))
    1.jpg

  • 方差
    方差是偏差的平方的平均值即mean(x-x.mean()**2)
    2.jpg

import numpy as np
'''
    NumPy - 统计函数
    NumPy 有很多有用的统计函数,用于从数组中给定的元素中查找最小,最大,百分标准差和方差等
'''

# a = np.random.randint(1,15,size = (3,3))
a = np.array([[1,2,3,4],[7,8,9,10]])

print(a)
#amin返回最小值
print('------------amin 返回最小值-------------')
print(np.amin(a,1)) #参数1 表示同行数据
print(np.amin(a,0)) #参数0 表示同列数据
#amax返回最大值
print('------------amax 返回最大值-------------')
print(np.amax(a,1))
print(np.amax(a,0))

#mean 平均值
print('------------mean 平均值-------------')
print(np.mean(a))
print(np.mean(a,0)) #求列平均值
print(np.mean(a,axis = 1)) #求行平均值

#标准差
arr2 = np.array([[1,2,3,4],[7,8,9,10]])
print(arr2)
# print(arr2-arr2.mean()) #平均值的偏差
print(((arr2-arr2.mean())**2).sum()/arr2.size)#平均值的偏差的平方的平均值
print(np.mean(((arr2-arr2.mean())**2)))#平均值的偏差的平方的平均值
print(np.sqrt(((arr2-arr2.mean())**2).sum()/arr2.size))
print(np.sqrt(np.mean(((arr2-arr2.mean())**2))))
print(np.std(arr2,0))
print('************************')
'''
    方差
    方差是偏差的平方的平均值即mean(x-x.mean()**2)
'''
arr3 = np.array([[1,2,3,4],[7,8,9,10]])
# print(np.var(arr3))
# print(arr3-arr3.mean())
print(((arr3-arr3.mean())**2).sum()/arr3.size)
print(np.mean((arr3-arr3.mean())**2))
print(np.var(arr3))

七、 np.where函数

np.where函数是三元表达式x if condition else y的矢量化版本,由此,我们就很清楚这个函数的作用了。

xarr = np.array([1,2,3,4,5])
yarr = np.array([6,7,8,9,10])
condition = xarr < yarr
#传统的三元表达式
# zip 函数接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),
# 然后返回由这些tuples组成的list(列表)
result1 = [x if c else y for (x,y,c) in zip(xarr,yarr,condition)]
print(result1)
result2 = np.where(condition,xarr,yarr)
print(result2)

案例:将数组中的所有异常数字替换为0,比如将NaN替换为0

arr = np.array([
    [1,2,np.NaN,4],
    [4,5,6,np.NaN],
    [np.inf,7,8,9],
    [np.inf,np.e,np.pi,4]
])

print('原数组:')
print(arr)
#设置条件
condition = np.isnan(arr) | np.isinf(arr)
print('结果:')
print(np.where(condition,0,arr))

八、 np.unique函数

np.unique函数的主要作用是将数组中的元素进行 去重操作(也就是只保存不重复的数据)

arr = np.array(['1','2','3','2','4','2','5','7','7'])
print('原始数组:')
for a in arr:
    print(a,end = ' ')
print()

print('去重数据:')
arr2 = np.unique(arr)
for a in arr2:
    print(a,end = ' ')
print()

输出:

原始数组:
1 2 3 2 4 2 5 7 7 
去重数据:
1 2 3 4 5 7

九、排序函数

  • numpy.sort()
    函数返回输入数组的排序副本
    numpy.sort(a,axis,kind,order)
    | a : |要排序的函数 |
    |—— |—– |
    | axis: |压着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序 |
    | kind: |默认为’quicksort’快速排序 |
    | order: |如果数组包含字段,则是要排序的字段 |
arr = np.array([[5,7],[8,1]])
print('我们的数组是:')
print(arr)
print('调用sort排序:')
print(np.sort(arr))
print('沿轴0排序')
print(np.sort(arr,axis = 0)) #按列排序
print(' sort 函数中排序字段')
# 在 sort 函数中排序字段
dt = np.dtype([('name',  'S10'),('age',  int)])
a = np.array([("raju",21),("anil",25),("ravi",  17), ("amar",27)], dtype = dt)
print('我们的数组是:')
print(a)
print(a['name'])
print('调用sort 按 name字段排序:')
print(np.sort(a,order = 'name'))
print('调用sort 按 age字段排序:')
print(np.sort(a,order = 'age'))
上一篇