您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

Python数据分析之numpy最强攻略

时间:2020-08-11 11:26:41  来源:  作者:
零基础入门Python数据分析之numpy最强攻略

 

本文的主要学习目标:

  • 熟练的掌握 numpy 数组相关的运算;
  • 熟练的使用 numpy 创建矩阵;
  • 理解矩阵转置和乘法;
  • 熟练的计算数据的相关系数、方差、协方差、标准差;
  • 理解并能够计算特征值与特征向量;
  • 理解可逆矩阵并能够计算矩阵的逆;
  • 熟练求解线性方程组;
  • 熟练计算向量和矩阵的范数;
  • 理解并计算奇异值分解;

numpy 数组及运算

扩展库 numpy 是 Python 支持科学计算的重要扩展库,是数据分析和科学计算领域如 scipy、pandas、sklearn 等众多扩展库中必备的扩展库之一,提供了强大的 N 维数组及其相关的运算、复杂的广播函数、C/C++和Fortran代码集成工具以及线性代数、傅里叶变换和随机数生成等功能。本次重点讲解数组和矩阵及其相关的运算。

创建数组

数组是用来存储若干数据的连续内存空间,其中的元素一般是相同类型的,例如都是浮点数。数组运算是学习数据分析和机器学习相关算法的重要基础。在我们处理实际数据的时候,总会用到大量的数组运算或者矩阵的运算,这些数据有的是通过文件直接读取的,有的则是根据实际需要生成的,当然还有些数据是实时采集的。

import numpy as np

np.array([1, 2, 3, 4, 5])
# -> array([1, 2, 3, 4, 5])

np.array(range(5))
# -> array([0, 1, 2, 3, 4])

np.array([1, 2, 3],[4, 5, 6])
# -> array([[1, 2, 3],
#			[4, 5, 6]])

np.arange(5)
#-> array([0, 1, 2, 3, 4])

np.arange(1, 10, 2)
#-> array([1, 3, 5, 7, 9])

np.linspace(0, 10, 11)
#-> array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])

np.linspace(0, 10, 11, endpoint=False)
#-> array([0.        , 0.90909091, 1.81818182, 2.72727273, 3.63636364,
#       4.54545455, 5.45454545, 6.36363636, 7.27272727, 8.18181818,
#       9.09090909])

np.logspace(0, 100, 10)
#-> array([1.00000000e+000, 1.29154967e+011, 1.66810054e+022, 2.15443469e+033,
#       2.78255940e+044, 3.59381366e+055, 4.64158883e+066, 5.99484250e+077,
#       7.74263683e+088, 1.00000000e+100])

np.logspace(1, 6, 5, base=2)
#-> array([ 2.        ,  4.75682846, 11.3137085 , 26.90868529, 64.        ])

np.zeros(3)
#-> array([0., 0., 0.])

np.ones(3)
#-> array([1., 1., 1.])

np.zeros((3, 3))
#-> array([[0., 0., 0.],
#       [0., 0., 0.],
#       [0., 0., 0.]])

np.ones((3, 3))
#-> array([[1., 1., 1.],
#       [1., 1., 1.],
#       [1., 1., 1.]])

np.identity(3)
#-> array([[1., 0., 0.],
#       [0., 1., 0.],
#       [0., 0., 1.]])

np.empty((3, 3))
#-> array([[1., 0., 0.],
#       [0., 1., 0.],
#       [0., 0., 1.]])

np.hamming(20)
#-> array([0.08      , 0.10492407, 0.17699537, 0.28840385, 0.42707668,
#       0.5779865 , 0.7247799 , 0.85154952, 0.94455793, 0.9937262 ,
#       0.9937262 , 0.94455793, 0.85154952, 0.7247799 , 0.5779865 ,
#       0.42707668, 0.28840385, 0.17699537, 0.10492407, 0.08      ])

np.blackman(20)
#-> array([-1.38777878e-17,  1.02226199e-02,  4.50685843e-02,  1.14390287e-01,
#        2.26899356e-01,  3.82380768e-01,  5.66665187e-01,  7.52034438e-01,
#        9.03492728e-01,  9.88846031e-01,  9.88846031e-01,  9.03492728e-01,
#        7.52034438e-01,  5.66665187e-01,  3.82380768e-01,  2.26899356e-01,
#        1.14390287e-01,  4.50685843e-02,  1.02226199e-02, -1.38777878e-17])

np.kaiser(12, 5)
#-> array([0.03671089, 0.16199525, 0.36683806, 0.61609304, 0.84458838,
#       0.98167828, 0.98167828, 0.84458838, 0.61609304, 0.36683806,
#       0.16199525, 0.03671089])

np.random.randint(0, 50, 5)
#-> array([ 6, 43, 33, 11,  5])

np.random.randint(0, 50, (3,5))
#-> array([[45, 30, 17, 31, 25],
#       [11, 32, 47, 48,  5],
#       [22, 29,  3,  9, 28]])

np.random.rand(10)
#-> array([0.53459796, 0.59163821, 0.11611952, 0.68199147, 0.03725451,
#       0.57498382, 0.15140171, 0.33914725, 0.90706282, 0.68518446])

np.random.standard_normal(5)
#-> array([-0.62939386, -0.16023864,  1.67463293, -0.44869975,  0.97008488])

np.random.standard_normal(size=(3, 4, 2))
#-> array([[[-0.7924237 , -2.02222271],
#        [-0.7360387 , -1.88832641],
#        [-0.43188511, -0.40672139],
#        [ 2.03058394,  1.007505  ]],
#
#       [[ 0.35664297,  1.9308035 ],
#        [ 0.56456596, -1.02357394],
#        [ 1.45042549, -0.59816538],
#        [-0.00659242,  0.15439743]],
#
#       [[-1.31088702, -0.167339  ],
#        [ 0.44439704,  0.00819551],
#        [-2.39637084, -0.07890167],
#        [ 0.53474018,  1.18425122]]])

np.diag([1, 2, 3, 4])
#-> array([[1, 0, 0, 0],
#       [0, 2, 0, 0],
#       [0, 0, 3, 0],
#       [0, 0, 0, 4]])

测试两个数组的对应元素是否足够接近

扩展库 numpy 提供了 isclose() 和 allclose() 函数来测试两个数组中对应位置的元素在允许误差的范围内是否相等,并可以接收绝对误差参数和相对误差参数.isclose()函数用来测试每一对元素是否相等并返回包含若干个 True/False 的列表。

isclose(a, b, rtol=le-05, atol=le-08, equal_man=False)
1

allclose()函数用来测试所有对应位置上的元素是否都相等并返回单个的True/False。

allclose(a, b, rtol=le-05, atol=le-08, equal_man=False)
1

下面以代码为例子讲解用法:

import numpy as np

x = np.array([1, 2, 3, 4.0001, 5])
y = np.array([1, 1.999, 3, 4.01, 5.1])

np.allclose(x, y)
#-> False

np.allclose(x, y, rtol=0.2)
#-> True

np.allclose(x, y, atol=0.2)
#-> True

np.isclose(x, y)
#-> [True False True False False]

np.isclose(x, y, atol=0.2)
#-> [True True True True True]

修改数组中的元素值

扩展库 numpy 支持多种方式修改数组中元素的值,既可以使用 Append()、insert() 函数在原数组的基础上追加或插入元素并返回新数组,也可以使用下标的方式直接修改数组中一个或多个元素的值。

import numpy as np

x = np.arange(8)
print(x)
#-> array([0, 1, 2, 3, 4, 5, 6, 7])

np.append(x, 8)
#-> array([0, 1, 2, 3, 4, 5, 6, 7, 8])

np.append(x, [9, 10])
#-> array([0, 1, 2, 3, 4, 5, 6, 7, 9, 10])

np.insert(x, 1, 8)
#-> array([0, 8 ,1, 2, 3, 4, 5, 6, 7])

print(x)
#-> array([0, 1, 2, 3, 4, 5, 6, 7])

x[3] = 8
print(x)
#-> array([0, 1, 2, 8, 4, 5, 6, 7])

x = np.array([[1, 2, 3],[4, 5, 6]])
x[0, 2] = 4
x[1:, 1:] = 1
print(x)
#-> array([[1, 2, 4],
#       [4, 1, 1]])

x[1:, 1:] = [1, 2]
print(x)
#-> array([[1, 2, 4],
#       [4, 1, 2]])

数组与标量的运算

扩展库 numpy 中的数组支持加减乘除幂运算等操作,计算结果为一个新的数组,其中每个元素为标量与原数组中每个元素进行计算的结果。使用时需要注意的是标量在前和在后的时候计算结果是截然不同的。

import numpy as np

x = np.array([1, 2, 3, 4, 5])
print(x)
#-> array([1, 2, 3, 4, 5])

print(x * 2)
#-> array([ 2,  4,  6,  8, 10])

print(x / 2)
#-> array([0.5, 1. , 1.5, 2. , 2.5])

print(x // 2)
#-> array([0, 1, 1, 2, 2], dtype=int32)

print(x ** 2)
#-> array([ 1,  4,  9, 16, 25], dtype=int32)

print(2 ** x)
#-> array([ 2,  4,  8, 16, 32], dtype=int32)

print(63 // x)
#-> array([63, 31, 21, 15, 12], dtype=int32)

数组与数组的运算

对两个等长数组进行算数运算后,得到一个新的数组,其中每个元素的值为原来的两个数组上对应的位置上的元素进行算数运算的结果。当数组大小不一样时,如果符合广播要求则进行广播,否则就报错并结束运行。

import numpy as np

np.array([1, 2, 3, 4]) + np.array([5, 6, 7, 8])
#-> array([ 6,  8, 10, 12])

np.array([1, 2, 3, 4]) + np.array([4])
#_> array([5, 6, 7, 8])

a = np.array([1, 2, 3])
print(a + a)
#-> array([2, 4, 6])

print(a * a)
#-> array([1, 4, 9])

print(a / a)
#-> array([1, 1, 1])

b = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(a * b)
#-> array([[ 1,  4,  9],
#       [ 4, 10, 18],
#       [ 7, 16, 27]])

数组排序

扩展库 numpy 的 argsort() 函数用来返回一个数组,其中的每个元素为原数组中元素的索引,表示应该把原数组中哪个位置的元素放到这个位置上面。另外, numpy 还提供了argmax() 函数和argmin() 函数,分布用来返回数组最大元素和最小元素的下标,而数组本身也提供了原地排序的方法 sort()。

import numpy as np

x = np.array([3, 1, 2])
np.argsort(x)
#-> array([1, 2, 0], dtype=int64)

x[_]
#-> array([1, 2, 3])

x.argmax(), x.argmin()
#-> (0, 1)

x.sort()
print(x)
#-> array([1, 2, 3])

x = np.random.randint(1, 10, (2, 5))
print(x)
#-> array([[2, 3, 6, 2, 3],
#       [1, 9, 7, 5, 3]])
x.sort(axis = 1)
print(x)
#-> array([[2, 2, 3, 3, 6],
#       [1, 3, 5, 7, 9]])

数据的内积运算

对于两个等长的数组 x 和 y ,其内积为两数组中对应的位置的元素乘积之和,计算公式如下:x*y = ∑ni=1sum_{i=1}^n∑i=1nxiyi扩展库 numpy 提供了 dot() 函数用来计算两个数组的内积,扩展库 numpy 中的数组也提供了 dot() 方法方法来计算另一个数组的内积,也可以借用内置 sum() 函数来计算两个数组的内积。

import numpy as np

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.dot(x, y))
#-> 32
print(x.dot(y))
#-> 32
print(sum(x*y))
#-> 32

访问数组中的元素

用户可以使用下标和切片的方法来访问数组中的某个或多个元素,形式非常灵活。

import numpy as np

b = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(b)
#-> array([[1, 2, 3],
#       [4, 5, 6],
#       [7, 8, 9]])

print(b[0][0])
#-> 1

print(b[0,2])
#-> 3

print(b[[0, 1]])
#-> array([[1, 2, 3],
#       [4, 5, 6]])

print(b[[0, 2, 1],[2, 1, 0]])
#-> array([3, 8, 4])

a = np.arange(10)
print(a)
#-> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

print(a[::-1])
#-> array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

c = np.arange(25)
c.shape = 5, 5
print(c)
#-> array([[ 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]])

print(c[0, 2:5])
#-> array([2, 3, 4])

print(c[2:5, 2:5])
#->array([[12, 13, 14],
#       [17, 18, 19],
#       [22, 23, 24]])

print(c[:, [2,4]])
#->array([[ 2,  4],
#       [ 7,  9],
#       [12, 14],
#       [17, 19],
#       [22, 24]])

print(c[[1,3]][:,[2, 4]])
#-> array([[ 7,  9],
#       [17, 19]])

数组对函数运算的支持

扩展库 numpy 提供了大量用于对数组进行计算的函数,可以用于对数组中所有元素进行同样的计算并返回新的数组,处理速度比使用循环要快得多。

import numpy as np

x = np.arange(0, 100, 10, dtype=np.floating)
print(x)
#-> array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90.])

print(np.sin(x))
#-> array([ 0.        , -0.54402111,  0.91294525, -0.98803162,  0.74511316,
#       -0.26237485, -0.30481062,  0.77389068, -0.99388865,  0.89399666])

x = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(np.cos(x))
#->array([[ 0.54030231, -0.41614684, -0.9899925 ],
#       [-0.65364362,  0.28366219,  0.96017029],
#       [ 0.75390225, -0.14550003, -0.91113026]])

print(np.round(np.cos(x)))
#->array([[ 1., -0., -1.],
#       [-1.,  0.,  1.],
#       [ 1., -0., -1.]])

print(np.ceil(x/2))
#->array([[1., 1., 2.],
#       [2., 3., 3.],
#       [4., 4., 5.]])

改变数组形状

扩展库 numpy 中的数组提供了 reshape() 和 resize() 两种方法,用来修改数组的形状,其中 reshape() 返回新数组但不会改变数组中的总数量,而 resize() 对数组进行原地修改后能根据需要进行补零或者丢弃某些元素。另外,还可以通过数组的 shape 属性直接原地修改数组的大小,除了 reshape() 和 resize() 方法,numpy 还提供同名的函数实现类似的功能并返回新的数组。

import numpy as np

x = np.arange(1, 11, 1)
print(x)
#-> array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

x.shape
#-> (10,)

x.size
#-> 10

x.shape = 2, 5
#-> array([[ 1,  2,  3,  4,  5],
#       [ 6,  7,  8,  9, 10]])

x.shape
#-> (2, 5)

x.shape = 5,-1
#-> array([[ 1,  2],
#       [ 3,  4],
#       [ 5,  6],
#       [ 7,  8],
#       [ 9, 10]])

x = x.reshape(2, 5)
print(x)
#-> array([[ 1,  2,  3,  4,  5],
#       [ 6,  7,  8,  9, 10]])

x = np.array(range(5))
x.reshape(1, 10)
#-> Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#ValueError: cannot reshape array of size 5 into shape (1,10)

x.resize((1, 10))
#-> array([[0, 1, 2, 3, 4, 0, 0, 0, 0, 0]])

np.resize(x, (1,3))
#-> array([[0, 1, 2]])

数组布尔运算

数组可以和标量或等长的数组进行关系运算,返回包含若干个 True/False 的数组。其中每个元素是原数组中元素与标量或另一个数组中对应位置上的元素的运算结果。数组也支持使用包含 True/False 的登场数组作为下标来访问其中的元素,返回 True 对应位置上的元素组成的数组。

import numpy as np

x = np.random.rand(10)
print(x)
#->array([0.07997063, 0.49599796, 0.6803197 , 0.03469489, 0.82135573,
#       0.74242199, 0.5898134 , 0.46247891, 0.3777993 , 0.23361106])

x > 0.5
#-> array([False, False,  True, False,  True,  True,  True, False, False, False])

x[x > 0.5]
#-> array([0.6803197 , 0.82135573, 0.74242199, 0.5898134 ])

sum((x > 0.4) & (x < 0.6))
#-> 3

np.all(x < 1)
#-> True

np.any(x > 0.8)
#-> True

a = np.array([1, 2, 3])
b = np.array([3, 2, 1])
a > b
#-> array([False, False,  True])

a[a > b]
#-> array([3])

a == b
#-> array([False,  True, False])

x = np.arange(10)
x[(x % 2 == 0) & (x>5)]
#-> array([6, 8])

x[(x % 2 == 0) | (x>5)]
#-> array([0, 2, 4, 6, 7, 8, 9])

分段函数

扩展库 numpy 提供了 where() 和 pircewise() 两个函数支持分段函数对数组的处理,其中 where() 函数适合对原数组中的元素进行“二值化”,根据数组中的元素是否满足指定的条件来决定返回 x 还是 y 。where() 函数的语法格式如下:where(condition, [x, y])piecewise() 函数可以实现更复杂的处理,函数格式如下:piecewise(x, condlist, funclist, *args, **kw)

import numpy as np

x = np.random.randint(0, 10, size = (1, 10))
print(x)
#-> array([[4, 6, 2, 2, 8, 5, 4, 8, 6, 8]])

np.where(x < 5, 0, 1)
#-> array([[0, 1, 0, 0, 1, 1, 0, 1, 1, 1]])

x.resize((2,5))
#-> array([[4, 6, 2, 2, 8],
#       [5, 4, 8, 6, 8]])

np.piecewise(x, [x<4, x>7], [lambda x:x*2, lambda x:x*3])
#-> array([[ 0,  0,  4,  4, 24],
#       [ 0,  0, 24,  0, 24]])

np.piecewise(x, [x<3, (3<x)&(x<5), x>7], [-1, 1, lambda x:x*4])
#-> array([[ 1,  0, -1, -1, 32],
#       [ 0,  1, 32,  0, 32]])

数组堆叠与合并

堆叠数组是指沿着特定的方向把多个数组合并到一起, numpy 的 hstack() 和 vsack() 函数分别用于多个数组的水平堆叠和垂直堆叠。

import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
np.hstack((arr1, arr2))
#-> array([1, 2, 3, 4, 5, 6])

arr3 = np.array([[1], [2], [3]])
arr4 = np.array([[4], [5], [6]])
print(arr3)
#-> array([[1],
#       [2],
#       [3]])
print(arr4)
#-> array([[4],
#       [5],
#       [6]])

np.hstack((arr3, arr4))
#-> array([[1, 4],
#       [2, 5],
#       [3, 6]])

np.vstack((arr3,arr4))
#-> array([[1],
#       [2],
#       [3],
#       [4],
#       [5],
#       [6]])

另外,numpy 的 concatenate() 函数也提供了类似的数组合并功能。其参数 axis 用于指定沿哪个方向或纬度进行合并,默认为0,也就是按行进行合并。

np.concatenate((arr1, arr2))
#-> array([1, 2, 3, 4, 5, 6])

np.concatenate((arr3, arr4))
#-> array([[1],
#       [2],
#       [3],
#       [4],
#       [5],
#       [6]])

np.concatenate((arr3, arr4),axis = 1)
#-> array([[1, 4],
#       [2, 5],
#       [3, 6]])

矩阵生成与常规操作

矩阵生成

矩阵和数组虽然在形式上很像,但矩阵是数学上的概念,而数组只是一种数据存储方式,二者是有本质区别的。例如,矩阵只能包含数字,而数组可以包含任意类型的数据;矩阵必须是二维的,数组可以是任意维的;乘法、幂运算等很多运算规则在矩阵和数组中都不一样。扩展库 numpy 中提供了 matrix() 函数可以用来把列表、元组、range()对象等python可迭代的对象转换为矩阵。

import numpy as np

x = np.matrix([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
y = np.matrix([1, 2, 3, 4, 5, 6])
print(x, y, x[1, 1], sep="nn")
#-> [[1 2 3]
# [4 5 6]
# [7 8 9]]
#
#[[1 2 3 4 5 6]]
#
#5

矩阵转置

矩阵转置是指对矩阵的行和列互换得到新矩阵的操作,原矩阵的第 i 行变为新矩阵的第 i 列,原矩阵的第 j 列变成新矩阵的第 j 行,一个 mn 的矩阵转置之后得到 nm 的矩阵。在 numpy 中,矩阵对象的属性 T 实现了转置的功能。

import numpy as np

x = np.matrix([[1, 2, 3],[4, 5, 6]])
y = np.matrix([1, 2, 3, 4, 5, 6])
print(x.T, y.T, sep="nn")
#-> [[1 4]
# [2 5]
# [3 6]]
#
#[[1]
# [2]
# [3]
# [4]
# [5]
# [6]]

查看矩阵特征

这里的矩阵特征主要是指矩阵的最大值、最小值、元素求和、平均值等,扩展库 numpy 中的矩阵提供了相应的 max() min() sum() mean()等方法。在大部分的矩阵方法中,都支持 axis 来指定计算方向,axis = 1 表示横向计算,axis = 0 表示纵向计算。对于 mn 的矩阵,沿 axis = 0 方向计算相当于对矩阵的从上到下“压扁”,最终得到 1n 的矩阵;沿 axis = 1 方向计算相当于对矩阵从左向右“压扁”,最终得到 m*1 的矩阵。

import numpy as np

x = np.matrix([[1, 2, 3],[4, 5, 6]])
print(x.mean(), end = "n===n")
print(x.mean(axis = 0), end = "n===n")
print(x.mean(axis = 0).shape, end = "n===n")
print(x.mean(axis = 1), end = "n===n")
print(x.mean(axis = 1).shape, end = "n===n")
print(x.sum(), end = "n===n")
print(x.max(axis = 1), end = "n===n")
print(x.argmax(axis = 1), end = "n===n")
print(x.diagonal(), end = "n===n")
print(x.nonzero(), end = "n===n")
#-> 3.5
#===
#[[2.5 3.5 4.5]]
#===
#(1, 3)
#===
#[[2.]
# [5.]]
#===
#(2, 1)
#===
#21
#===
#[[3]
# [6]]
#===
#[[2]
# [2]]
#===
#[[1 5]]
#===
#(array([0, 0, 0, 1, 1, 1], dtype=int64), #array([0, 1, 2, 0, 1, 2], dtype=int64))
#===

计算相关系数矩阵

相关系数矩阵是一个对称矩阵,其中对角线上的元素都为1,表示自相关系数。非对角线上的元素表示互相关系数,每个元素的绝对值都小于等于1,反映变量变化趋势的相似程度。例如,如果 2*2 的相关系数矩阵中非对角线元素的值都大于0,表示两个信号正相关,其中一个信号变大时另一个信号也变大,变化方向一致,或者说一个信号的变化对另一个信号的影响是“正面的”、积极的。相关系数的绝对值越大,表示两个信号互相影响的程度就越大。扩展库 numpy 提供了 corrcoef() 函数用来计算相关系数矩阵。

import numpy as np

print(np.corrcoef([1, 2, 3, 4],[4, 3, 2, 1]))
#-> [[ 1. -1.]
# [-1.  1.]]

print(np.corrcoef([1, 2, 3, 4],[8, 3, 2, 1]))
#-> [[ 1.         -0.91350028]
# [-0.91350028  1.        ]]

print(np.corrcoef([1, 2, 3, 4],[1, 2, 3, 4]))
#-> [[1. 1.]
# [1. 1.]]

print(np.corrcoef([1, 2, 3, 4],[1, 2, 3, 40]))
#-> [[1.        0.8010362]
# [0.8010362 1.       ]]

计算方差、协方差、标准差

扩展库 numpy 提供了用来计算协方差 cov() 函数和用来计算标准差的 std() 函数。

import numpy as np

print(np.cov([1, 1, 1, 1, 1]))
#-> 0.0

print(np.std([1, 1, 1, 1, 1]))
#-> 0.0

x = [-2.1, -1, 4.3]
y = [3, 1.1, 0.12]
x = np.vstack((x,y))
print(x)
#-> array([[-2.1 , -1.  ,  4.3 ],
#       [ 3.  ,  1.1 ,  0.12]])

print(np.cov(x))
#-> array([[11.71      , -4.286     ],
#       [-4.286     ,  2.14413333]])

print(np.cov(x, y))
#-> array([[11.71      , -4.286     , -4.286     ],
#       [-4.286     ,  2.14413333,  2.14413333],
#       [-4.286     ,  2.14413333,  2.14413333]])

print(np.std(x))
#-> 2.2071223094538484

print(np.std(x, axis = 1))
#-> array([2.79404128, 1.19558447])

print(np.cov(x))
#-> array([[11.71      , -4.286     ],
#       [-4.286     ,  2.14413333]])

计算特征值与特征向量

对于 n*n 方阵A,如果存在标量 λ 和 n为非0向量x,使得UA˙x = λx 成立,那么称 λ 是方阵A的一个特征值,x为对应于λ的特征向量。从几何意义来讲,矩阵乘以一个向量,是对这个向量进行了一个变换,从一个坐标系变到另一个坐标系。在变换过程中,向量主要进行旋转和缩放这两种变化。如果矩阵乘以一个向量之后,向量只发生了缩放变化而没有进行旋转,那么这个向量本身就是该矩阵的一个特征向量,缩放的比例就是特征值。换句话说,特征向量是对向量进行旋转之后理想的坐标轴之一,而特征值则是原向量在坐标轴上的投影或者该坐标轴对原向量的贡献。特征值越大,有特征向量组成了该矩阵的一组基,也就是新坐标系的轴。有了特征值和特征向量之后,向量就可以在另一个坐标系中进行表示。扩展库 numpy 的线性代数子模块 linalg 中提供了用来计算特征值与特征向量的 eig() 函数,参数可以是列表、numpy的数组、矩阵等等。

a = np.array([[1,-3,3],[3,-5,3],[6,-6,4]])
e, v = np.linalg.eig(a) # 特征值与特征向量
print(e, v)
#-> [ 4.+0.00000000e+00j -2.+1.10465796e-15j -2.-1.10465796e-15j] [[-0.40824829+0.j          0.24400118-0.40702229j  0.24400118+0.40702229j]
# [-0.40824829+0.j         -0.41621909-0.40702229j -0.41621909+0.40702229j]
# [-0.81649658+0.j         -0.66022027+0.j         -0.66022027-0.j        ]]

print(np.dot(e, v))
#-> [0.81649658+4.50974724e-16j 3.12888345-8.14044580e-01j
# 3.12888345+8.14044580e-01j]

print(e*v)
#-> [[-1.63299316+0.00000000e+00j -0.48800237+8.14044580e-01j
#  -0.48800237-8.14044580e-01j]
# [-1.63299316+0.00000000e+00j  0.83243817+8.14044580e-01j
#   0.83243817-8.14044580e-01j]
# [-3.26598632+0.00000000e+00j  1.32044054-7.29317578e-16j
#   1.32044054+7.29317578e-16j]]

print(np.isclose(np.dot(a, v),e*v)) # 验证两者是否相等
#-> [[ True  True  True]
# [ True  True  True]
# [ True  True  True]]

print(np.linalg.det(a-np.eye(3,3)*e)) # 行列式|a-λe|的值应该是0,det()是计算行列式的函数
#-> 5.965152994198125e-14j

计算机矩阵

对于 n*n 的矩阵

零基础入门Python数据分析之numpy最强攻略

 

如果存在另一个矩阵

零基础入门Python数据分析之numpy最强攻略

 

使得二者乘积为单位矩阵,即A˙B=B˙A=I那么称矩阵 A是可逆矩阵或者非奇异矩阵,称矩阵B为矩阵A的逆矩阵,即B=A<sup>-1</sup>.可逆矩阵的行列式不为0。扩展库 numpy 的线性代数子模块 linalg 中提供了用来计算逆矩阵的函数 inv() 。要求参数是可逆矩阵,形式可以是列表、numpy数组、矩阵等等。

x = np.matrix([[1,2,3],[4,5,6],[7,8,0]])
y = np.linalg.inv(x)
print(y)
#-> matrix([[-1.77777778,  0.88888889, -0.11111111],
#        [ 1.55555556, -0.77777778,  0.22222222],
#        [-0.11111111,  0.22222222, -0.11111111]])

print(x*y) # 对角线元素为1,其他元素为0或近似0
#-> matrix([[ 1.00000000e+00,  5.55111512e-17,  1.38777878e-17],
#        [ 5.55111512e-17,  1.00000000e+00,  2.77555756e-17],
#        [ 1.77635684e-15, -8.88178420e-16,  1.00000000e+00]])

print(y*x)
#-> matrix([[ 1.00000000e+00, -1.11022302e-16,  0.00000000e+00],
#        [ 8.32667268e-17,  1.00000000e+00,  2.22044605e-16],
#        [ 6.93889390e-17,  0.00000000e+00,  1.00000000e+00]])

求解线性方程组

线性方程组

零基础入门Python数据分析之numpy最强攻略

 

可以写成矩阵相乘的形式ax=b
其中,a 为 n * n 的矩阵,x 和 b 为 n * 1 的矩阵。
扩展库 numpy 的线性代数子模块 linalg 中提供了求解线性方程组的 solve() 函数和求解线性方程组最小二乘解的 lstsq() 函数,参数可以是列表、numpy数组、矩阵。

a = np.array([[3,1],[1,2]])
b = np.array([9,8])
x = np.linalg.solve(a,b)
print(x)
#-> array([2., 3.])

print(np.dot(a,x)) # 验证
#-> array([9., 8.])

print(np.linalg.lstsq(a,b)) # 最小二乘解,返回解、余项、a的秩、a的奇异值
#-> (array([2., 3.]), array([], dtype=float64), 2, array([3.61803399, 1.38196601]))

函数向量化

python 的扩展库 numpy 本身提供了大量函数都具有向量化的特点,并且可以把普通的函数向量化,从而python操作向量更方便。例如 numpy 中矩阵不支持 math 标准库中的阶乘函数 factorial() ,而扩展库 numpy 也没有直接提供这个功能,这个时候就可以通过函数向量化来解决这个问题。

import numpy as np
mat = np.matrix([[1,2,3],[4,5,6]])
print(mat)
#-> matrix([[1, 2, 3],
#        [4, 5, 6]])

import math
math.factorial(mat) #不支持,出错
#-> TypeError: only size-1 arrays can be converted to Python scalars

vec = np.vectorize(math.factorial) # 函数向量化
print(vec(mat))
#-> matrix([[  1,   2,   6],
#        [ 24, 120, 720]])


Tags:Python 数据分析   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
本文的主要学习目标: 熟练的掌握 numpy 数组相关的运算; 熟练的使用 numpy 创建矩阵; 理解矩阵转置和乘法; 熟练的计算数据的相关系数、方差、协方差、标准差; 理解并能够计算特...【详细内容】
2020-08-11  Tags: Python 数据分析  点击:(48)  评论:(0)  加入收藏
数据分析肯定需要数据,这个数据一般都是来自实际学习工作业务中的,比如学校的学生成绩,淘宝京东的销售数据,视频网站不同种类的视频播放点击量等。自己练习的话,除了可以去一些公...【详细内容】
2020-07-13  Tags: Python 数据分析  点击:(70)  评论:(0)  加入收藏
来源:Python爱好者社区ID:python_shequ作者:深度沉迷学习 Python语言:简要概括一下Python语言在数据分析、挖掘场景中常用特性: 列表(可以被修改),元组(不可以被修改) 字典(<k,v>结构...【详细内容】
2019-09-25  Tags: Python 数据分析  点击:(103)  评论:(0)  加入收藏
▌简易百科推荐
Python 是一个很棒的语言。它是世界上发展最快的编程语言之一。它一次又一次地证明了在开发人员职位中和跨行业的数据科学职位中的实用性。整个 Python 及其库的生态系统使...【详细内容】
2021-12-27  IT资料库    Tags:Python 库   点击:(1)  评论:(0)  加入收藏
菜单驱动程序简介菜单驱动程序是通过显示选项列表从用户那里获取输入并允许用户从选项列表中选择输入的程序。菜单驱动程序的一个简单示例是 ATM(自动取款机)。在交易的情况下...【详细内容】
2021-12-27  子冉爱python    Tags:Python   点击:(4)  评论:(0)  加入收藏
有不少同学学完Python后仍然很难将其灵活运用。我整理15个Python入门的小程序。在实践中应用Python会有事半功倍的效果。01 实现二元二次函数实现数学里的二元二次函数:f(x,...【详细内容】
2021-12-22  程序汪小成    Tags:Python入门   点击:(32)  评论:(0)  加入收藏
Verilog是由一个个module组成的,下面是其中一个module在网表中的样子,我只需要提取module名字、实例化关系。module rst_filter ( ...); 端口声明... wire定义......【详细内容】
2021-12-22  编程啊青    Tags:Verilog   点击:(7)  评论:(0)  加入收藏
运行环境 如何从 MP4 视频中提取帧 将帧变成 GIF 创建 MP4 到 GIF GUI ...【详细内容】
2021-12-22  修道猿    Tags:Python   点击:(5)  评论:(0)  加入收藏
面向对象:Object Oriented Programming,简称OOP,即面向对象程序设计。类(Class)和对象(Object)类是用来描述具有相同属性和方法对象的集合。对象是类的具体实例。比如,学生都有...【详细内容】
2021-12-22  我头秃了    Tags:python   点击:(9)  评论:(0)  加入收藏
所谓内置函数,就是Python提供的, 可以直接拿来直接用的函数,比如大家熟悉的print,range、input等,也有不是很熟,但是很重要的,如enumerate、zip、join等,Python内置的这些函数非常...【详细内容】
2021-12-21  程序员小新ds    Tags:python初   点击:(5)  评论:(0)  加入收藏
Hi,大家好。我们在接口自动化测试项目中,有时候需要一些加密。今天给大伙介绍Python实现各种 加密 ,接口加解密再也不愁。目录一、项目加解密需求分析六、Python加密库PyCrypto...【详细内容】
2021-12-21  Python可乐    Tags:Python   点击:(7)  评论:(0)  加入收藏
借助pyautogui库,我们可以轻松地控制鼠标、键盘以及进行图像识别,实现自动抢课的功能1.准备工作我们在仓库里提供了2个必须的文件,包括: auto_get_lesson_pic_recognize.py:脚本...【详细内容】
2021-12-17  程序员道道    Tags:python   点击:(13)  评论:(0)  加入收藏
前言越来越多开发者表示,自从用了Python/Pandas,Excel都没有打开过了,用Python来处理与可视化表格就是四个字&mdash;&mdash;非常快速!下面我来举几个明显的例子1.删除重复行和空...【详细内容】
2021-12-16  查理不是猹    Tags:Python   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条