(레코드) Python 기계 학습 - Numpy 배열의 고급 작업


머리말

이전 Numpy 기초

http://t.csdn.cn/eNkIt


1. 스태킹 작업

stack스태킹의 의미는 스태킹의 의미이며 소위 스태킹은 ndarray두 개의 물체를 함께 쌓아 새로운 ndarray물체를 형성하는 것입니다. 쌓이는 방향에 따라 hstackvstack가지로 나눌 수 있다.

(1) h스택

특정 회사에 소속된 경우 HR회사 직원의 기본 정보를 기록해야 합니다. 지금까지 다음 정보를 기록했을 수 있습니다.

작업 번호 이름 생일 연락처
1 장산 1988.12 13323332333
2 리시 1987.2 15966666666
왕 우 1990.1 13777777777
4 토요일 1996.4 13069699696

세상에는 끊임없는 수요가 없고 상사가 회사의 모든 직원의 거주지 주소와 호적 주소를 기록하도록 요청합니다. 이때 이러한 추가 정보를 기록해야 합니다. 그러면 다음과 같은 것이 있을 수 있습니다.

거주지 주소 거주지 주소
강소성 난징시 루커우 공항 기숙사 202호 장시성 난창시 홍구탄신구 천월향토 A동 2201호
강소성 난징시 루커우 공항 기숙사 203호 후난성 주저우시 톈위안구 신톈화푸 11동 303호
강소성 난징시 루커우 공항 기숙사 204호 사천성 청두시 무후사 재정착공동체 1동 701호
강소성 난징시 루커우 공항 기숙사 205호 저장성 항저우시 시후구 싱톈가 B동 1204호

다음으로, 이전에 기록한 정보를 방금 기록한 추가 정보와 통합하고 소스로 변환해야 합니다.

작업 번호 이름 생일 연락처 거주지 주소 거주지 주소
1 장산 1988.12 13323332333 강소성 난징시 루커우 공항 기숙사 202호 장시성 난창시 홍구탄신구 천월향토 A동 2201호
2 리시 1987.2 15966666666 강소성 난징시 루커우 공항 기숙사 203호 후난성 주저우시 톈위안구 신톈화푸 11동 303호
왕 우 1990.1 13777777777 강소성 난징시 루커우 공항 기숙사 204호 사천성 청두시 무후사 재정착공동체 1동 701호
4 토요일 1996.4 13069699696 강소성 난징시 루커우 공항 기숙사 205호 저장성 항저우시 시후구 싱톈가 B동 1204호

통합할 때 두 개의 테이블(2차원 배열)을 가로 방향으로 함께 쌓고 새로운 테이블(2차원 배열)로 접합하는 것을 볼 수 있습니다. hstack이러한 동작을 ( horizontal stack) 라고 합니다 .

NumPyhstack해당 기능을 구현하는 기능을 제공하며 hstack사용 hstack루틴 코드는 다음과 같습니다.

import numpy as np

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

'''
将a和b按元组中的顺序横向拼接
结果为:[[8, 8, 1, 8],
[0, 0, 0, 4]]
'''
print(np.hstack((a,b)))

c = np.array([[1, 2], [3, 4]])

'''
将a,b,c按元组中的顺序横向拼接
结果为:[[8, 8, 1, 8, 1, 2],
[0, 0, 0, 4, 3, 4]]
'''
print(np.hstack((a,b,c)))

(2)v스택

귀하는 여전히 특정 회사에 속해 HR있으며 다음과 같이 회사 직원에 대한 일부 정보를 기록했습니다.

작업 번호 이름 생일 연락처
1 장산 1988.12 13323332333
2 리시 1987.2 15966666666
왕 우 1990.1 13777777777
4 토요일 1996.4 13069699696

오늘 두 명의 새로운 동료가 회사에 합류했습니다. 다음과 같이 그들의 정보를 기록해야 합니다.

작업 번호 이름 생일 연락처
5 류 치 1986.5 13323332331
6 후 바 1997.3 15966696669

그런 다음 새로 채용된 동료의 정보와 이미 채용된 직원의 정보를 통합해야 합니다.

작업 번호 이름 생일 연락처
1 장산 1988.12 13323332333
2 리시 1987.2 15966666666
왕 우 1990.1 13777777777
4 토요일 1996.4 13069699696
5 류 치 1986.5 13323332331
6 후 바 1997.3 15966696669

이 경우 통합할 때 두 개의 테이블(2차원 배열)을 세로 방향으로 함께 쌓고 새로운 테이블(2차원 배열)로 접합합니다. vstack이러한 동작을 ( vertical stack) 라고 합니다 .

NumPyvstack해당 기능을 구현하는 기능을 제공하며 vstack사용 vstack루틴 코드는 다음과 같습니다.

    import numpy as np
    a = np.array([[8, 8], [0, 0]])
    b = np.array([[1, 8], [0, 4]])
    '''
    将a和b按元组中的顺序纵向拼接
    结果为:[[8, 8]
            [0, 0]
            [1, 8]
            [0, 4]]
    '''
    print(np.vstack((a,b)))
    c = np.array([[1, 2], [3, 4]])
    '''
    将a,b,c按元组中的顺序纵向拼接
    结果为:[[8 8]
            [0 0]
            [1 8]
            [0 4]
            [1 2]
            [3 4]]
    '''
    print(np.vstack((a,b,c)))

(3) 시도

feature1테스트 사례 입력은 부분적으로는 function 에 있는 내용을 나타내고 부분적으로 feature1feature2function 에 있는 내용을 나타내는 사전입니다 feature2.

테스트 입력:{'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. ]

import numpy as np


def get_mean(feature1, feature2):
    '''
    将feature1和feature2横向拼接,然后统计拼接后的ndarray中每列的均值
    :param feature1:待`hstack`的`ndarray`
    :param feature2:待`hstack`的`ndarray`
    :return:类型为`ndarray`,其中的值`hstack`后每列的均值
    '''
    #********* Begin *********#
    a=np.hstack((feature1,feature2))
    return np.mean(a, axis=0)#沿着a对象的0轴求均值
    #********* End *********#

2. 비교, 마스킹 및 부울 논리

(1) 비교

부울 마스크를 사용하여 배열의 값을 보고 조작합니다. 산술 연산자와 마찬가지로 비교 연산자는 numpy일반 함수로 구현됩니다. 비교 연산자 및 해당 일반 함수는 다음과 같습니다.

비교 연산자 범용 기능
== np.equal
!= np.not_equal
< np.less
<= np.less_equal
> np.greater
>= np.greater_equal

이러한 비교 연산자 일반 함수는 모든 모양과 크기의 배열에서 사용할 수 있습니다. 예는 다음과 같습니다.

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)
'''
输出:array([ True, False, True, True])
'''

print(data["score"]>60)
'''
输出:array([False, True, True, False])
'''

print(data["score"]>=60)
'''
输出:array([False, True, True, True])
'''

print(data["score"]<=60)
'''
输出:array([ True, False, False, True])
'''

print(data["age"]!=9)
'''
输出:array([ True, True, True, False])
'''

print((data["age"]/2)==(np.sqrt(data["age"])))
'''
输出:array([ True, False, False, False])
'''

(2) 마스크로서의 부울 배열

보다 강력한 패턴은 일부 작업을 수행하기 위해 데이터의 하위 데이터 세트를 선택하는 마스크로 부울 배열을 사용하는 것입니다.

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)
'''
输出:[(b'Alice', 4, 40. )
(b'Bob', 11, 85.5)
(b'Cathy', 7, 68. )
(b'Doug', 9, 60. )]
'''


print(data["score"]>60) #使用比较运算得的一个布尔数组
'''
输出:[False True True False]
'''

print(data[data["score"]>60]) #进行简单的索引,即掩码操作将值为True的选出
'''
输出:[(b'Bob', 11, 85.5) (b'Cathy', 7, 68. )]
'''

(3) 부울 논리

Python비트 논리 연산자와 함께 사용됩니다. 논리 연산자에 해당하는 numpy일반적인 기능은 다음과 같습니다.

논리 연산자 범용 기능
& np.bitwise_and
| np.bitwise_or
^^ np.bitwise_xor
~ np.bitwise_not
print(np.count_nonzero(data["age"]<10))#统计数组中True的个数
'''
输出:3
'''

#还可以用np.sum(),输出结果和count_nonzero一样,sum()的好处是可以沿着行或列进行求和
print(np.sum(data["age"]<10))

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

print(np.all(data["age"]>10))#是否都大于10岁
'''
输出:False
'''

print(data[data["age"]>10])#打印年龄大于10的信息
'''
输出:array([(b'Bob', 11, 85.5)],
dtype=[('name', 'S10'), ('age', '<i4'), ('score', '<f8')])
'''

(4) 시도

테스트 입력:[[ 3 ,15, 9 ,11 , 7],[ 2, 0 , 8, 19 ,16],[ 6 , 6, 16 , 9, 5],[ 7 , 5 , 2 , 6 ,13]] 10

예상 출력:[15 11 19 16 16 13]

import numpy as np


def student(num,input_data):
    result=[]
    # ********* Begin *********#

    result=np.array(input_data)#实例化数组
    result=result[result>num]#将数组中大于num的元素放入result的数组中

    # ********* End *********#
    return result


3. 팬시 인덱스 및 불리언 인덱스

(1) 팬시 인덱스

花式索引(Fancy Indexing)是NumPy用来描述使用整型数组(这里的数组,可以是NumPy的数组,也可以是python自带的list作为索引的术语,其意义是根据索引数组的值作为目标数组的某个轴的下标来取值。

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

示例代码如下:

import numpy as np

arr = np.array(['zero','one','two','three','four'])

'''
打印arr中索引为1和4的元素
结果为:['one', 'four']
'''
print(arr[[1,4]])

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

'''
打印arr中索引为1和0的行
结果为:[[4, 5, 6],
[1, 2, 3]]
'''
print(arr[[1, 0]])

'''
打印arr中第2行第1列与第3行第2列的元素
结果为:[4, 8]
'''
print(arr[[1, 2], [0, 1]])

 (2)布尔索引

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

我们可以想办法根据我们的需求,构造出布尔数组,然后再通过布尔索引来实现筛选数据的功能。

假设有公司员工绩效指数的数据如下(用一个一维的ndarray表示),现在想要把绩效指数大于3.5的筛选出来进行股权激励。

那首先就要构造出布尔数组,构造布尔数组很简单,performance > 3.5即可。此时会生成想要的布尔数组。

有了布尔数组就可以使用布尔索引来实现筛选数据的功能了。

示例代码如下:

import numpy as np

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

'''
筛选出绩效高于3.5的数据
结果为:[3.75, 3.75]
'''
print(performance[performance > 3.5])

'''
筛选出绩效高于3.25并且低于4的数据
注意:&表示并且的意思,可以看成是and。&左右两边必须加上()
结果为:[3.5 3.75 3.5 3.75]
'''
print(performance[(performance > 3.25) & (performance < 4)])

(3)尝试

测试输入: ["d","a","A","p","b","I","C","K"]

预期输出: ['A' 'I' 'C' 'K']

import numpy as np

def student(input_data):
    result=[]
    #********* Begin *********#
    result=np.array(input_data)
    result=result[(result>='A') & (result<='Z')]#输出A~Z的字符

    # ********* End *********#
    return result

四、广播机制

(1)广播

当两个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维度并不形同,但是它们可以进行相减操作,这就是通过广播机制来实现的。

(2)广播的原则

如果两个数组的后缘维度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,)。可以说前者是二维的,而后者是一维的。但是它们的后缘维度相等,arr1的第二维长度为3,和arr2的维度相同。

arr1arr2shape并不一样,但是它们可以执行相加操作,这就是通过广播完成的,在这个例子当中是将arr2沿着0轴进行扩展。

我们再看一个例子:

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]]
'''

arr1shape(4,3)arr2shape(4,1),它们都是二维的,但是第二个数组在1轴上的长度为1,所以,可以在1轴上面进行广播。

(3)尝试

测试输入:

[[9, 3, 1], [7, 0, 6], [4, 6, 3]] [1, 5, 9] [[9], [6], [7]]

预期输出:

  1. [[19 17 19]
  2. [14 11 21]
  3. [12 18 19]]
import numpy as np

def student(a,b,c):
    result=[]
    # ********* Begin *********#

    a=np.array(a)
    b=np.array(b)
    c=np.array(c)
    result=a+b+c


    # ********* End *********#
    return result

五、线性代数

(1)numpy的线性代数

常用的numpy.linalg函数:

函数 说明
dot 矩阵乘法
vdot 두 벡터의 내적
그만큼 행렬의 행렬식 계산
인보이스 정사각 행렬의 역함수 계산
svd 특이값 분해(SVD) 계산
해결하다 선형 방정식 시스템 Ax=b 풀기, A는 정사각 행렬
매트 두 배열의 행렬 곱

1. 도트()

이 함수는 두 배열의 내적을 반환합니다. 2차원 벡터의 경우 효과는 행렬 곱셈과 동일하고, 1차원 배열의 경우 벡터의 내적이며, 1차원 N배열의 a경우 마지막 축과 두 b번째 의 마지막 축까지 . (두 개의 행렬을 곱하여 행과 열을 곱함)

 

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

2. 그것()

입력 행렬의 행렬식을 계산하는 데 사용됩니다.

    a = np.array([[14, 1], [6, 2]])
    a=linalg.det(a)
    print(a)
    '''
    输出:21.999999999999996
    '''

3. 인브()

정사각 행렬의 역함수를 계산하는 데 사용됩니다. 역행렬의 정의 차원 A, B, 와 같은 두 개의 정방행렬이 있으면 가역행렬이라 AB = BA = E하고 의 역행렬이고 항등 행렬이다.ABAE

a=np.array([[1,2],[3,4]])

b=linalg.inv(a)

print(np.dot(a,b))
'''
输出:array([[1.0000000e+00, 0.0000000e+00],
[8.8817842e-16, 1.0000000e+00]])
'''

4. 해결()

선형 방정식에 대한 솔루션을 계산하는 데 사용됩니다.

다음 연립방정식을 가정합니다. 3x+2y=7 x+4y=14;

행렬 형식으로 작성: [[3,2][1,4]]* [[x],[y]]= [[7],[14]];

위의 방정식을 푸는 코드는 다음과 같습니다.

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

5. matmul()

두 배열의 행렬 곱을 반환합니다. 인수에 1차원 배열이 있는 경우 차원에 추가하여 행렬로 승격 1하고 곱한 후에 뺍니다.

    a=[[3,4],[5,6]]
    b=[[7,8],[9,10]]
    np.matmul(a,b)
    '''
    输出:array([[ 57,  64],
           [ 89, 100]])
    '''
    b=[7,8]
    np.matmul(a,b)
    '''
    输出:array([53, 83])
    '''

6. svd()

특이값 분해는 함수 를 푸는 데 사용되는 행렬 분해 방법입니다 SVD.

    a=[[0,1],[1,1],[1,0]]
    linalg.svd(a)
    '''
    输出:(array([[-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) 시도

테스트 입력:

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

예상 출력:

  1. [[-7.2]
  2. [13.6]]
from numpy import linalg
import numpy as np
def student(input_data):
    '''
    将输入数据筛选性别为男,再进行线性方程求解
    :param input_data:类型为`list`的输入数据
    :return:类型为`ndarray`
    '''
    result=[]
    # ********* Begin *********#
    a=np.array(input_data)
    x=[]
    y=[]
    for i in a:#以数组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)#解线性方程

    # ********* End *********#
    return result

추천

출처blog.csdn.net/qq_43659681/article/details/130178837