zoukankan      html  css  js  c++  java
  • NumPy-矩阵部分

    NumPy-矩阵部分

    NumPy 简介

    numpy可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多。

    安装NumPy

    pip install numpy
    

    导入 NumPy

    在导入 NumPy 库时,大多数情况下你会看到的一个约定,是将其命名为 np

    import numpy as np
    

    数据类型和形状

    NumPy 中处理数字的最常见方式是通过 ndarray 对象。它们与 Python 列表相似,但是可以有任意数量的维度。而且,ndarray 支持快速的数学运算。

    NumPy里面的数据类型比Python的多。python只有intfloat。在NumPy中除了 Python 的 int,你可以使用 uint8int8uint16int16 等类型。ndarray中的每一项必须具有相同的类型,和c类似。

    创建包含一个标量的 NumPy 数组:

    s=np.array(5)
    

    可以通过检查数组的 shape 属性来查看数组的形状。

    s.shape
    

    它会打印出结果,即一对空括号 ()。这表示它的维度为零。

    即使标量位于数组中,你仍然可以像正常标量一样使用它们。你可以键入:

    x = s + 3
    

    x 现在将等于 8。如果你检查 x 的类型,会发现它可能是 numpy.int64,因为它在使用 NumPy 类型,而不是 Python 类型。

    创建一个向量:

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

    检查向量的 shape 属性,它将返回表示向量的一维长度的单个数字。在上面的示例中,v.shape 会返回 (3,) 。

    现在有了数字,你可以看到 shape 是一个元组,其中包含每个 ndarray 的维度的大小。对于标量,它只是一个空的元组,但是向量有一个维度,所以元组包含一个数字和一个逗号。(Python 不能将 (3) 理解为具有一个项的元组,所以它需要逗号。

    你可以使用索引访问向量中的元素,如下所示:

    x = v[1]
    

    现在 x 等于 2

    NumPy 还支持高级索引技术。例如,要访问第二个元素及其后面的项,你可以这样写:

    v[1:]
    
    

    然后它会返回数组 [2, 3]

    创建矩阵

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

    创建了一个包含数字 1 到 9 的 3x3 矩阵。

    它的 shape 属性将返回元组 (3, 3)

    所以要在上面的矩阵中找到数字 6,你可以访问 m[1][2]

    张量

    张量可以有更多的维度。

    如,要创建一个 3x3x2x1 的张量

    t = np.array([[[[1],[2]],[[3],[4]],[[5],[6]]],[[[7],[8]],[[9],[10]],[[11],[12]]],[[[13],[14]],[[15],[16]],[[17],[17]]]])
    

    t[2][1][1][0] 将返回 16

    更改形状

    更改数据的形状,而不实际更改其内容。例如,你可能有一个一维的向量,但是需要一个二维的矩阵。实现它的方式有两种。

    假设你有以下向量:

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

    调用 v.shape 会返回 (4,)。但如果你想要一个 1x4 矩阵呢?你可以使用 reshape 函数,就像这样:

    x = v.reshape(1,4)
    

    调用 x.shape 会返回 (1,4)。如果你想要一个 4x1 矩阵,可以这样做:

    x = v.reshape(4,1)
    
    

    reshape 函数不只是添加大小为 1 的维度。

    关于更改 NumPy 数组的形状还有一点:如果你看到经验丰富的 NumPy 使用者的代码,经常会看到他们使用一种特殊的切片语法,而不是调用 reshape。使用该语法,前面的两个示例会是这样的:

    x = v[None, :]
    

    或者

    x = v[:, None]
    

    NumPy里面的矩阵运算

    将矩阵元素都加一个数

    values = [1,2,3,4,5]
    values = np.array(values) + 5
    # 现在 values 是包含 [6,7,8,9,10] 的一个 ndarray
    

    NumPy 实际上有用于加法、乘法等运算的函数。

    以下两行是等价的:

    x = np.multiply(some_array, 5)
    x = some_array * 5
    

    矩阵归零:

    m *= 0
    
    # 现在 m 中的每个元素都是 0,无论它有多少维度
    

    矩阵的平方值:

    x = m * m(或者如果你要将值赋值回 m,则是 m *= m
    示例:

    a = np.array([[1,3],[5,7]])
    a
    # 显示以下结果:
    # array([[1, 3],
    #        [5, 7]])
    
    b = np.array([[2,4],[6,8]])
    b
    # 显示以下结果:
    # array([[2, 4],
    #        [6, 8]])
    
    a + b
    # 显示以下结果:
    #      array([[ 3,  7],
    #             [11, 15]])
    

    不兼容的形状,会收到一个错误:

    a = np.array([[1,3],[5,7]])
    a
    # 显示以下结果:
    # array([[1, 3],
    #        [5, 7]])
    c = np.array([[2,3,6],[4,5,9],[1,8,7]])
    c
    # 显示以下结果:
    # array([[2, 3, 6],
    #        [4, 5, 9],
    #        [1, 8, 7]])
    
    a.shape
    # 显示以下结果:
    #  (2, 2)
    
    c.shape
    # 显示以下结果:
    #  (3, 3)
    
    a + c
    # 显示以下结果:
    # ValueError: operands could not be broadcast together with shapes (2,2) (3,3)
    

    要获得矩阵乘积,可以使用 NumPy 的 matmul 函数。

    如果你有兼容的形状,那就像这样简单:

    a = np.array([[1,2,3,4],[5,6,7,8]])
    a
    # 显示以下结果:
    # array([[1, 2, 3, 4],
    #        [5, 6, 7, 8]])
    a.shape
    # 显示以下结果:
    # (2, 4)
    
    b = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
    b
    # 显示以下结果:
    # array([[ 1,  2,  3],
    #        [ 4,  5,  6],
    #        [ 7,  8,  9],
    #        [10, 11, 12]])
    b.shape
    # 显示以下结果:
    # (4, 3)
    
    c = np.matmul(a, b)
    c
    # 显示以下结果:
    # array([[ 70,  80,  90],
    #        [158, 184, 210]])
    c.shape
    # 显示以下结果:
    # (2, 3)
    

    如果你的矩阵具有不兼容的形状,则会出现以下错误:

    np.matmul(b, a)
    # 显示以下错误:
    # ValueError: shapes (4,3) and (2,4) not aligned: 3 (dim 1) != 2 (dim 0)
    

    tf.multiply是点乘,tf.matmul是矩阵乘法.

    转置

    NumPy 中获得矩阵的转置,可以直接访问其 T 属性,还有一个 transpose() 函数也可以返回同样的结果。

    例如:

    m = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
    m
    # 显示以下结果:
    # array([[ 1,  2,  3,  4],
    #        [ 5,  6,  7,  8],
    #        [ 9, 10, 11, 12]])
    
    m.T
    # 显示以下结果:
    # array([[ 1,  5,  9],
    #        [ 2,  6, 10],
    #        [ 3,  7, 11],
    #        [ 4,  8, 12]])
    

    NumPy 在进行转置时不会实际移动内存中的任何数据 - 只是改变对原始矩阵的索引方式 - 所以是非常高效的。

    但是,这也意味着你要特别注意修改对象的方式,因为它们共享相同的数据。例如,对于上面同一个矩阵 m,我们来创建一个新的变量 m_t 来存储 m 的转置。然后看看如果我们修改 m_t 中的值,会发生什么:

    m_t = m.T
    m_t[3][1] = 200
    m_t
    # 显示以下结果:
    # array([[ 1,   5, 9],
    #        [ 2,   6, 10],
    #        [ 3,   7, 11],
    #        [ 4, 200, 12]])
    
    m
    # 显示以下结果:
    # array([[ 1,  2,  3,   4],
    #        [ 5,  6,  7, 200],
    #        [ 9, 10, 11,  12]])
    
    

    注意它是如何同时修改转置和原始矩阵的!这是因为它们共享相同的数据副本。所以记住,将转置视为矩阵的不同视图,而不是完全不同的矩阵。

  • 相关阅读:
    Silverlight & Blend动画设计系列一:偏移动画(TranslateTransform)
    如何在DeepEarth中进行图形绘制(点、线、多边形以及自定义图片图层)
    Bing Maps进阶系列六:使用Silverlight剪切(Clip)特性实现Bing Maps的迷你小地图
    解决 ICTCLAS 2009 Windows_JNI_32 在 Web Project无法使用的方法
    XListControl 改变颜色 行高
    设置 java.library.path其实是在 Apache Tomcat 的任务栏 Icon中设置
    ICTCLAS 2009 JNI_32 遇到MyEclipse Web Project下无法运行
    10分钟开始使用ICTCLAS Java版
    boost regex_search 找出所有 匹配串
    Boost 1_37_0 的安装以及在VC6.0中的使用
  • 原文地址:https://www.cnblogs.com/hjw1/p/8385921.html
Copyright © 2011-2022 走看看