Numpy库入门

前言

  在我学习机器学习的过程中,我频繁遇到了Python中处理数据的相关库,主要有Numpy,Matplotlib和Pandas库,它们分别对应着数据的表示,展示和统计分析,熟练掌握这些库的应用可以提高我们对数据的处理能力。所以我依据慕课上嵩天老师的《Python数据分析与展示》对相关内容进行总结。 课程链接
  我们知道Python有列表(List)、字典(Set)、元组(Tuple)、集合(Dictionary)等基本数据类型,而Python本身是没有数组类型的。在使用数组的过程中,会发现它和列表很相似,一个列表可以存储一个一维的数组,列表的嵌套即可实现多维数组。当然它们也有不同,比如列表可以存储不同类型的数据,而数组只能存储相同类型的数据,所以在通用性上数组不及列表。那么我们为什么要引入数组呢?原因就在于数组在科学计算中可以发挥它的优势,减少循环运算的次数,提高运行效率。可以对比一下:

import numpy as np

# 计算a^2 + b^3

# 列表计算
def pysum():
    a = [0, 1, 2, 3, 4]
    b = [5, 6, 7, 8, 9]
    c = []
    for i in range(len(a)):
        c.append(a[i]**2 + b[i]**3)
    return c

# 数组计算
def npsum():
    a = np.array([0, 1, 2, 3, 4])
    b = np.array([5, 6, 7, 8, 9])
    c = a**2 + b**3
    return c

  所以在列表之外引入数组主要有以下原因:

  • 数组对象可以去掉元素间运算所需的循环,使一维向量更像单个数据
  • 设置专门的数组对象,经过优化,可以提升这类应用的运算速度
  • 科学计算中,一个维度所有数据的类型往往相同,而数组对象采用相同的数据类型,有助于节省运算和存储空间

Numpy的数组对象—ndarray

(一)创建一个ndarray类型数组

1.用列表、元组等类型创建

在这里插入图片描述

import numpy as np
a = np.array([0, 1, 2, 3, 4])          # 列表
b = np.array((0, 1, 2, 3, 4))          # 元组
c = np.array([[0, 1, 2], (3, 4, 5)])   # 列表和元组混合,最外层必须用[]括起来
print(a)
print(b)
print(c)

  运行结果:

[0 1 2 3 4]
[0 1 2 3 4]
[[0 1 2]
 [3 4 5]]

2.使用Numpy中的函数创建

在这里插入图片描述

import numpy as np
a = np.arange(5)
b = np.ones((2, 5))
c = np.zeros((2, 5))
d = np.full((2, 5), 3)
e = np.eye(3)

print(a)
print(b)
print(c)
print(d)
print(e)

  运行结果:

[0 1 2 3 4]
[[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]]
[[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
[[3 3 3 3 3]
 [3 3 3 3 3]]
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

在这里插入图片描述

import numpy as np

a = np.linspace(1, 10, 4)      # 从1到10等间距生成4个数
print(a)
b = np.linspace(1, 10, 4)
c = np.concatenate((a, b))
print(c)

  运行结果:

[ 1.  4.  7. 10.]
[ 1.  4.  7. 10.  1.  4.  7. 10.]

(二)ndarray对象属性

在这里插入图片描述

import numpy as np
a = np.array([[0, 1, 2, 3, 4],
              [5, 6, 7, 8, 9]])

print(a.ndim)      # 维度是二维的
print(a.shape)     # 形状是两行5列
print(a.size)      # 大小是2*5
print(a.dtype)     # 数据类型是整型
print(a.itemsize)  # 整型是4个字节

  运行结果:

2
(2, 5)
10
int32
4

(三)ndarray数组变换

1.维度变换

在这里插入图片描述
注意reshape和resize的区别,一个不改变原数组,形成新数组,一个改变原数组

import numpy as np
a = np.ones((2, 3, 4))
b = a.reshape((3, 8))
print(b)
print(a)                # a没有改变
a.resize((3, 8))        # a改变了
print(a)

a = np.ones((2, 3, 4))
c = a.swapaxes(0, 1)   # 0维和1维进行交换
print(c)
d = a.flatten()
print(d)

  运行结果:

[[1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1.]]
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
[[1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1.]]
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]]]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

2.数组类型变换

在这里插入图片描述
astype会产生一个新数组,其类型为new_type

import numpy as np
a = np.ones((2, 3))
print(a)
b = a.astype(np.int)   # 将数据变为整型
print(b)

  运行结果:

[[1. 1. 1.]
 [1. 1. 1.]]
[[1 1 1]
 [1 1 1]]

3.数组转换为列表

在这里插入图片描述

import numpy as np
a = np.ones((2, 3))
print(a)
b = a.tolist()
print(b)

  运行结果:

[[1. 1. 1.]
 [1. 1. 1.]]
[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]

(四)数组的索引和切片

  • 和列表的切片和索引相同
import numpy as np
# 一维数组
a = np.array([0, 1, 2, 3, 4, 5, 6])
print(a[2])                     # 索引
# 切片
print(a[ 1 : 6 : 2])            # 从1号位置到6号位置每隔2空取一位数,最后一位不包括

# 多维数组
a = np.arange(24).reshape(2, 3, 4)
print(a[1, 2, 3])               # 索引
# 切片
print(a[:, 1, -3])              # 0维全取,1维取1,2维取倒数第三个
print(a[:, 1:3, :])             # 0维全取,1为取1和2,2维全取
print(a[:, :, ::2])             # 0,1维全取,2维以步长为2跳跃取

  运行结果:

2
[1 3 5]
23
[ 5 17]
[[[ 4  5  6  7]
  [ 8  9 10 11]]

 [[16 17 18 19]
  [20 21 22 23]]]
[[[ 0  2]
  [ 4  6]
  [ 8 10]]

 [[12 14]
  [16 18]
  [20 22]]]

(五)数组的运算

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(六)数组和矩阵的区别

  在Numpy中,数组和矩阵形式很像,在运算的时候却有较大的差异,因此我主要从它们运算的层面总结一下它们的区别。

1.创建数组和矩阵

import numpy as np
# 创建一个二维的数组和矩阵
a = np.array([[0, 1, 2, 3, 4],
              [5, 6, 7, 8, 9]])
b = np.mat([[0, 1, 2, 3, 4],
              [5, 6, 7, 8, 9]])
print(a)
print(type(a))
print(b)
print(type(b))

  运行结果:

[[0 1 2 3 4]
 [5 6 7 8 9]]
<class 'numpy.ndarray'>
[[0 1 2 3 4]
 [5 6 7 8 9]]
<class 'numpy.matrix'>

  可以看出两者创建方法类似,输出结果除了类型不同其余完全相同。另外,两者可以用np.array和np.mat进行类型互换。

2.相关运算

  • 加减运算
import numpy as np

a = np.array([[0, 1, 2],
              [3, 4, 5]])
b = np.array([[1, 2, 3],
              [4, 5, 6]])
c = np.array([[0, 1, 2],
              [3, 4, 5]])
d = np.array([[1, 2, 3],
              [4, 5, 6]])
print(a+b)
print(c+d)
print(a+c)

  运行结果:

[[ 1  3  5]
 [ 7  9 11]]
[[ 1  3  5]
 [ 7  9 11]]
[[ 0  2  4]
 [ 6  8 10]]

  可以看出,两者加减运算完全相同,甚至可以进行相互运算,若数组和矩阵进行相互运算,运算结果为数组类型

  • 数乘运算
import numpy as np

a = np.array([[0, 1, 2],
              [3, 4, 5]])
b = np.mat([[1, 2, 3],
              [4, 5, 6]])
print(a*10)
print(b*10)

  运行结果:

[[ 0 10 20]
 [30 40 50]]
[[10 20 30]
 [40 50 60]]

  数乘运算完全相同

  • 点乘运算
import numpy as np

a = np.array([[0, 1],
              [3, 4]])
b = np.mat([[0, 1],
              [3, 4]])
print(a*a)
print(b*b)

print(np.dot(a, a))
print(np.dot(b, b))

  运行结果:

[[ 0  1]
 [ 9 16]]
[[ 3  4]
 [12 19]]
[[ 3  4]
 [12 19]]
[[ 3  4]
 [12 19]]

  可以看出,当用乘号*分别对数组和矩阵相乘时,矩阵做的是点乘运算,而数组做的是对应元素相乘的运算;当用np.dot的时候,两者都是点乘运算

  • 转置运算
import numpy as np

a = np.array([[0, 1],
              [3, 4]])
b = np.mat([[0, 1],
              [3, 4]])
print(a.T)
print(b.T)

  运行结果:

[[0 3]
 [1 4]]
[[0 3]
 [1 4]]

  两者转置运算完全相同

  • 求逆运算
import numpy as np

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

# print(a.I)          # 报错:AttributeError: 'numpy.ndarray' object has no attribute 'I'
print(b.I)

print(np.linalg.inv(a))
print(np.linalg.inv(b))

  运行结果:

[[-1.33333333  0.33333333]
 [ 1.          0.        ]]
[[-1.33333333  0.33333333]
 [ 1.          0.        ]]
[[-1.33333333  0.33333333]
 [ 1.          0.        ]]

  可见,求逆运算中.I操作只适用于矩阵,inv()操作适合两者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值