numpy数组的相关操作

numpy数组的相关操作

本文为机器学习课程中的笔记。

一、堆叠操作

stack

stack的意思是堆叠的意思,所谓的堆叠就是将两个ndarray对象堆叠在一起组合成一个新的ndarray对象。根据堆叠的方向不同分为hstack以及vstack两种。

hstack

hstack为水平堆叠,示例如下:

import numpy as np

a = np.array([[8, 8], [0, 0]])
b = np.array([[1, 8], [0, 4]])
c = np.array([[1, 2], [3, 4]])

print(np.hstack((a, b,c)))
# [[8 8 1 8 1 2]
#  [0 0 0 4 3 4]]
vstack

vstack为竖直方向堆叠,示例如下:

import numpy as np

a = np.array([[8, 8], [0, 0]])
b = np.array([[1, 8], [0, 4]])
c = np.array([[1, 2], [3, 4]])

print(np.vstack((a, b, c)))
'''
[[8 8]
 [0 0]
 [1 8]
 [0 4]
 [1 2]
 [3 4]]
'''

测试题目

测试输入:
{'feature1':[[1, 2, 3, 4], [4, 3, 2, 1], [2, 3, 4, 5]], 'feature2':[[1], [2], [3]]}

预期输出:
[2.33333333 2.66666667 3. 3.33333333 2. ]

def get_mean(feature1, feature2):
    '''
    将feature1和feature2横向拼接,然后统计拼接后的ndarray中每列的均值
    :param feature1:待`hstack`的`ndarray`
    :param feature2:待`hstack`的`ndarray`
    :return:类型为`ndarray`,其中的值`hstack`后每列的均值
    '''
    c = np.hstack((feature1, feature2))
    d = np.mean(c, 0)
    return d

二、比较、掩码和布尔逻辑

比较

在许多情况下,数据集可能不完整或因无效数据的存在而受到污染。我们要基于某些准则来抽取、修改、计数或对一个数组中的值进行其他操作时,就需要掩码,我们使用 布尔掩码 来查看和操作数组中的值。

比较运算符在numpy中通过通用函数来实现,比较运算符和其对应的通用函数如下:

比较运算符通用函数
==np.equal
!=np.not_equal
<np.less
<=np.less_equal
>np.greater
>=np.greater_equal

下面给出简单示例:

import numpy as np

data = np.array([('Alice', 4, 40), ('Bob', 11, 85.5), ('Cathy', 7, 68.0), ('Doug', 9, 60)],
              dtype = [("name", "S10"), ("age", "int"), ("score", "float")])  #构造结构化数组

print(data["age"] < 10)
# [ True False  True  True]

print(data["score"] > 60)
# [False  True  True False]

print((data["age"]/2)==(np.sqrt(data["age"])))
# [ True False False False]

布尔数组作掩码

在上面的比较中我们会得到一个布尔数组,再将其进行简单的索引,即掩码操作将值为True的选出输出,简单示例:

import numpy as np

data = np.array([('Alice', 4, 40), ('Bob', 11, 85.5), ('Cathy', 7, 68.0), ('Doug', 9, 60)],
              dtype = [("name", "S10"), ("age", "int"), ("score", "float")])  #构造结构化数组

print(data["score"] > 60)
print(data[data["score"]>60])

# [False  True  True False]
# [(b'Bob', 11, 85.5) (b'Cathy',  7, 68. )]

布尔逻辑

简而言之就是逻辑运算,结合Python的逐位逻辑运算符一起使用。逻辑运算符对应numpy中的通用函数如下表:

逻辑运算符通用函数
&np.bitwise_and
|np.bitwise_or
^np.bitwise_xor
~np.bitwise_not

简单示例:

import numpy as np

data = np.array([('Alice', 4, 40), ('Bob', 11, 85.5), ('Cathy', 7, 68.0), ('Doug', 9, 60)],
              dtype = [("name", "S10"), ("age", "int"), ("score", "float")])  #构造结构化数组

print(np.sum(data["age"]<10))
print(np.count_nonzero(data["age"]<10))#统计数组中True的个数
# 3

print(np.any(data["score"]<60))#是否有不及格的
# True

print(data[data["age"]>10])#打印年龄大于10的信息 
# [(b'Bob', 11, 85.5)]

三、花式索引与布尔索引

花式索引

花式索引是根据索引数组的值作为目标数组的某个轴的下标来取值。

使用一维整型数组作为索引,如果被索引数组(ndarray)是一维数组,那么索引的结果就是对应位置的元素;如果被索引数组(ndarray)是二维数组,那么就是对应下标的行。如下图所示:

请添加图片描述

简单示例:

import numpy as np

arr_1 = np.array(['zero', 'one', 'two', 'three', 'four'])
arr_2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print(arr_1[[1, 4]])
# ['one' 'four']
print(arr_2[[1, 0]])
# [[4 5 6]
#  [1 2 3]]
print(arr[[1, 2], [0, 1]])
# 输出第二行第一列,第一行第二列的的数据
# [4 8]

布尔索引

我们可以通过一个布尔数组来索引目标数组,以此找出与布尔数组中值为True的对应的目标数组中的数据,从而达到筛选出想要的数据的功能。如下图所示:PS:需要注意的是,布尔数组的长度必须与被索引数组对应的轴的长度一致)
请添加图片描述

不过这样看似十分麻烦,在前面我们通过比较得到过布尔数组,通过此种方式即可得到我们所需要筛选的数据,简单示例:

import numpy as np

arr = np.array([3.25, 3.5, 3.75, 3.5, 3.25, 3.75])

print((arr > 3.25) & (arr < 4))
# [False  True  True  True False  True]
print(arr[(arr > 3.25) & (arr < 4)])
# [3.5  3.75 3.5  3.75]

四、广播机制

广播是什么

两个ndarray对象的相加、相减以及相乘都是对应元素之间的操作,类比数学,就是同行同列形式矩阵的运算。而当两个ndarray对象的形状并不相同的时候,我们可以通过扩展数组的方法来实现相加、相减、相乘等操作,这种机制叫做广播(broadcasting

比如,一个二维的ndarray对象减去列平均值,来对数组的每一列进行取均值化处理:

import numpy as np

# arr为4行3列的ndarray对象
arr = np.random.randn(4,3)
# arr_mean为有3个元素的一维ndarray对象
arr_mean = arr.mean(axis=0)
# 对arr的每一列进行取均值化处理
demeaned = arr - arr_mean

上面代码中的arrarr_mean维度并不形同,但是它们可以进行相减操作,这就是通过广播机制来实现的。

广播的原则

广播的原则:如果两个数组的后缘维度trailing dimension,即从末尾开始算起的维度)的轴长度相符,或其中的一方的长度为1,则认为它们是广播兼容的,广播会在缺失或长度为1的维度上进行。

广播主要发生在两种情况,一种是两个数组的维数不相等,但是它们的后缘维度的轴长相符,另外一种是有一方的长度为1

import numpy as np

arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]])
arr2 = np.array([1, 2, 3])
arr_sum = arr1 + arr2
print(arr_sum)
'''  
[[1 2 3]  
 [2 3 4]  
 [3 4 5]  
 [4 5 6]]  
'''

arr1shape(4,3)arr2shape(3,)。一个二维一个一维,但后缘维度相同,也可以依次相加,而这个过程就是通过广播实现的。

请添加图片描述

相同的,列也可以按着这样规则实现类似的操作,简单示例:

import numpy as np
arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]])   #arr1.shape = (4,3)  
arr2 = np.array([[1],[2],[3],[4]])    #arr2.shape = (4, 1)
arr_sum = arr1 + arr2  
print(arr_sum)
'''    
[[1 1 1]  
 [3 3 3]  
 [5 5 5]  
 [7 7 7]]  
'''  

请添加图片描述

五、线性代数

线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分,一般我们使用*对两个二维数组相乘得到的是一个元素级的积,而不是一个矩阵点积。因此numpy提供了线性代数函数库linalg,该库包含了线性代数所需的所有功能。

常用的numpy.linalg函数:

函数说明
dot矩阵乘法
vdot两个向量的点积
det计算矩阵的行列式
inv计算方阵的逆
svd计算奇异值分解(SVD)
solve解线性方程组 Ax=b,A是一个方阵
matmul两个数组的矩阵积

常用函数

**dot():**该函数返回俩个数组的点积。对于二维向量,效果等于矩阵乘法;对于一维数组,它是向量的内积;对于N维数组,它是a的最后一个轴上的和与b的倒数第二个轴的乘积。

import numpy as np

a = np.array([[1,2],[3,4]])
a1 = np.array([[5,6],[7,8]])
print(np.dot(a, a1))
# [[19 22]
#  [43 50]]

**det():**该函数用于计算输入矩阵的行列式。

import numpy as np
from numpy import linalg

a = np.array([[14, 1], [6, 2]])
a = linalg.det(a)
print(a)
# 21.999999999999996  

**inv():**该函数用于计算方阵的逆矩阵。逆矩阵的定义维如果两个方阵AB,使得AB = BA = E,则A称为可逆矩阵,BA的逆矩阵,E为单位矩阵。

import numpy as np
from numpy import linalg

a = np.array([[1, 2], [3, 4]])
b = linalg.inv(a)
print(np.dot(a, b)) 
# [[1.0000000e+00 0.0000000e+00]
# [8.8817842e-16 1.0000000e+00]]

**solve():**该函数用于计算线性方程的解。

假设有如下方程组:3x+2y=7 x+4y=14

写成矩阵的形式:[[3,2][1,4]]*[[x],[y]]=[[7],[14]]

解如上方程组代码如下:

import numpy as np
from numpy import linalg

a = np.array([[3,2], [1,4]])
b = np.array([[7],[14]])
print(linalg.solve(a,b))
'''  
 输出:[[0. ],  
       [3.5]]
 最后解出x=0,y=3.5  
'''  

**matmul():**函数返回两个数组的矩阵乘积。如果参数中有一维数组,则通过在其维度上附加1来提升为矩阵,并在乘法之后去除。

import numpy as np

a=[[3,4],[5,6]]
b=[[7,8],[9,10]]
print(np.matmul(a,b))
# [[ 57  64]
#  [ 89 100]]

b=[7,8]
print(np.matmul(a,b))
# [53 83]

**svd():**奇异值分解是一种矩阵分解的方法,该函数用来求解SVD

import numpy as np
from numpy import linalg

a=[[0,1],[1,1],[1,0]]
print(linalg.svd(a))
'''  
输出:[[-4.08248290e-01,  7.07106781e-01,  5.77350269e-01],  
       [-8.16496581e-01,  2.64811510e-17, -5.77350269e-01],  
       [-4.08248290e-01, -7.07106781e-01,  5.77350269e-01]]), array([1.73205081, 1.        ]), array([[-0.70710678, -0.70710678],  
       [-0.70710678,  0.70710678]] 
'''  

测试题目

测试输入:

[["男",2,4,40],["女",8,3,17],["男",8,6,24]]

预期输出:

[[-7.2]   [13.6]]  

提示:测试数据的方程为2x+4y=408x+6y=24

from numpy import linalg
import numpy as np
def student(input_data):
    '''
    将输入数据筛选性别为男,再进行线性方程求解
    '''
    result=[]
    a=np.array(input_data)
    x=[]
    y=[]
    for i in a:
        if i[0]=="男":
            x.append([int(i[1]),int(i[2])])
            y.append([int(i[-1])])
    if x==[] and y==[]:
        return result
    x=np.array(x)
    y=np.array(y)
    result=linalg.solve(x,y)
    return result
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值