前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 科学计算的基石 numpy(一)

python 科学计算的基石 numpy(一)

作者头像
我是一条小青蛇
发布2019-10-23 17:04:49
9070
发布2019-10-23 17:04:49
举报
文章被收录于专栏:青笔原创青笔原创

1. 简单介绍

行业常说的“数据分析三剑客”或者“机器学习三剑客”,指的就是 numpy(计算), matplotlib(可视化), pandas(分析) 这三个 python 库。如果拿自然科学学科类比,matplotlib 相当于“物理学”,pandas 相当于“化学”,而 numpy 就是“数学”, 是其他学科赖以立足的“基石”。

numpy 之所以是基石,是因为 numpy 为 matplotlib 和 pandas 等提供了底层数据结构和计算支持。而 numpy 核心数据结构就是多维数组(ndarray: N-dimensional array)。

2. 准备工作

这个小节过渡有点突兀,但是为了下一步顺利运行代码,不得不强行插播这条“准备工作”。

2.1 安装

2.1.1 检查是否安装

代码语言:javascript
复制
conda list | grep numpy

或:

代码语言:javascript
复制
pip freeze | grep numpy

2.1.2 安装

已安装,请跳过。

代码语言:javascript
复制
conda install numpy

或:

代码语言:javascript
复制
pip install numpy

2.1.3 更新

已安装,可选择更新。

代码语言:javascript
复制
conda update numpy

或:

代码语言:javascript
复制
pip install --upgrade numpy

2.2 导入

np 为行业惯例缩写。

代码语言:javascript
复制
import numpy as np

3. 多维数组(numpy.ndarray: N-dimensional array)

如果熟悉 matlab (矩阵实验室),就知道 matlab 科学计算建立在“矩阵”之上。而,numpy 的多维数组有异曲同工之妙。

3.1 创建

3.1.1 使用 np.array() 创建

以下通过一个二维列表创建一个 numpy 多维数组(numpy.ndarray) 。在 numpy 中,维度这个概念也叫 ,英文叫Axes ,因此,这里创建的二维数组,我们也可以称之为为 2 的多维数组,它包含了 2 个轴(Axis)。数组的 shape 属性是一个元组,对应多维数组每个 轴(Axis) 长度;size 属性是多维数组所有元素个数,它等于 shape 所有元素的乘积。

说起来很复杂,但是实际很简单,通过下面的打印输出,我们可以很直观的理解,各个属性之间的关系。

代码语言:javascript
复制
na = np.array([[1, 2, 3], [4, 5, 6]])

print(
    """
    对象类型:\t{}\n
    形状:\t{}\n
    维度(秩):\t{}\n
    元素个数:\t{}\n
    元素类型:\t{}\n
    """
    .format(type(na), na.shape, na.ndim, na.size, na.dtype))

na
代码语言:javascript
复制
    对象类型:    <class 'numpy.ndarray'>

    形状:    (2, 3)

    维度(秩):    2

    元素个数:    6

    元素类型:    int64







array([[1, 2, 3],
       [4, 5, 6]])
3.1.2 使用 np.zeros() 创建

如果不是事先就知道各元素的数值,使用 np.array() 的方式,难免有些繁琐,相比之下,只是先初始化一个全为 0 的多维数组,np.zeros() 无疑是更适合的选择。使用 np.zeros() 只需提供 shape 参数,也是第一个位置参数,就可以创建指定 shape 的多维数组,并将数组所有元素填充为 0 。

代码语言:javascript
复制
na = np.zeros((2, 3))

print("dtype: ", na.dtype)

na
代码语言:javascript
复制
dtype:  float64





array([[0., 0., 0.],
       [0., 0., 0.]])

从上面打印的 dtype 属性可以看到,默认元素的数据类型是 float64 。当然,如果不想使用默认类型,可以通过 dtype 参数来设置。

代码语言:javascript
复制
na = np.zeros((2, 3), dtype="uint8")

print("dtype: ", na.dtype)

na
代码语言:javascript
复制
dtype:  uint8





array([[0, 0, 0],
       [0, 0, 0]], dtype=uint8)
3.1.3 使用 np.ones() 创建

np.ones() 和 np.zeros 除了填充的不是 0,而是 1,其他都一样。

代码语言:javascript
复制
np.ones((2, 3), dtype="float")
代码语言:javascript
复制
array([[1., 1., 1.],
       [1., 1., 1.]])
3.1.4 np.arange()

range() 的 numpy 版本实现。传入 start, end, step 参数创建一个1维 numpy 数组。

代码语言:javascript
复制
np.arange(2, 10, 2)
代码语言:javascript
复制
array([2, 4, 6, 8])

虽然 np.arange() 方法只能创建 1 维数组,但是借助 numpy 数组的 reshape() 方法可以在 size 不变的情况下,改变 shape 。注意,reshape() 方法是 numpy 数组实例的方法,因此,它适用于任何想要“重塑”shape场景,包括下面介绍的 np.linsapce() 使用场景。

代码语言:javascript
复制
np.arange(2, 13, 2).reshape(2, 3)
代码语言:javascript
复制
array([[ 2,  4,  6],
       [ 8, 10, 12]])

除了 reshape() 方法可以改变 shape 外,还有一个方法 resize() 也有相同的功能,区别是,reshape() 不会改变原来的数组,而 resize 会改变。

代码语言:javascript
复制
a = np.arange(2, 13, 2)
b = a.reshape(2, 3)

print("after call a.reshape():")
print("a.shape", a.shape)
print("b.shape", b.shape)
a.resize(2, 3)
print("after call a.resize():")
print("a.shape", a.shape)
代码语言:javascript
复制
after call a.reshape():
a.shape (6,)
b.shape (2, 3)
after call a.resize():
a.shape (2, 3)
3.1.5 np.linspace()

和 np.arange() 很像,也是创建一个 start 到 end 区间的1维 numpy 数组。但有两点不同:

  1. linsapce 第3个参数不是步长,而是区间内的多少个点
  2. 结果包含 end ,而 np.arange() 不包含 end
代码语言:javascript
复制
np.linspace(2, 10, 5)
代码语言:javascript
复制
array([ 2.,  4.,  6.,  8., 10.])
3.1.6 np.random.random()

指定 shape 生成随机数填充。

代码语言:javascript
复制
np.random.random((2, 3))
代码语言:javascript
复制
array([[0.22031976, 0.91591833, 0.63773627],
       [0.92104449, 0.69246379, 0.82988843]])
3.1.7 np.random.normal(mu, sigma, len)

创建均值为 mu , 标准差为 sigma, 长度为 len 标准正态分布的一维数组。

代码语言:javascript
复制
import matplotlib.pyplot as plt
%matplotlib inline

mu = 2
sigma = 0.5
v = np.random.normal(mu, sigma, 10000)

plt.hist(v, bins=50, density=1)
plt.show()

3.2 读取

3.2.1 元组索引

元组长度等于数组维度(Axes 秩),也就是多维数组的每个轴(Axis)都有个索引,元组括号可省略。

代码语言:javascript
复制
na = np.random.random((2, 3))

print(na[(1, 2)])
print(na[1, 2])
代码语言:javascript
复制
0.7547734386512726
0.7547734386512726
3.2.2 普通多维列表方式
代码语言:javascript
复制
na[1][2]
代码语言:javascript
复制
0.7547734386512726

3.3 统计运算

3.3.1 求最大值
代码语言:javascript
复制
v = np.random.normal(10, 1, 10000)

v.max()
代码语言:javascript
复制
13.949035793082137
3.3.2 求最小值
代码语言:javascript
复制
v.min()
代码语言:javascript
复制
6.31475048427698
3.3.3 求和
代码语言:javascript
复制
v.sum()
代码语言:javascript
复制
100051.11447780298
3.3.4 求均值
代码语言:javascript
复制
v.mean()
代码语言:javascript
复制
10.005111447780298
3.3.5 求标准差
代码语言:javascript
复制
v.std()
代码语言:javascript
复制
0.996315432751019
3.3.6 求中位数
代码语言:javascript
复制
np.median(v)
代码语言:javascript
复制
10.005551763169866

3.4 为什么要使用 numpy 多维数组

到此,你可能会有疑问,感觉 numpy 多维数组也不过如此,和列表差不多啊。对,从结构和使用方式上,的确 numpy 多维数组和列表有诸多相似的地方。在大数据分析,机器学习上尤其是深度学习,等需要对大量数据进行计算的场景,它的性能将远超普通列表。

下面计算一个长度为 300,000,000 (3亿)的数组的均值,分布使用列表和 numpy 数组计算。前者用了 15 秒,后者只用不到 2 毫秒。为什么会有这么大的差距,原因在于,numpy 底层运算是用 C 语言实现的,而 C 语言的性能相比于 python 是不言而喻的。

代码语言:javascript
复制
from time import time

a = list(range(300000000))
na = np.array(na)

start_time = time()
sum(a) / len(a)
print("calculate mean by list cost time {} s".format(time() - start_time))

start_time = time()
na.mean()
print("calculate mean by numpy.ndarray cost time {} s".format(time() - start_time))
代码语言:javascript
复制
calculate mean by list cost time 20.95879817008972 s
calculate mean by numpy.ndarray cost time 0.0011792182922363281 s
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-102,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 简单介绍
  • 2. 准备工作
    • 2.1 安装
      • 2.1.1 检查是否安装
        • 2.1.2 安装
          • 2.1.3 更新
            • 2.2 导入
            • 3. 多维数组(numpy.ndarray: N-dimensional array)
              • 3.1 创建
                • 3.1.1 使用 np.array() 创建
                • 3.1.2 使用 np.zeros() 创建
                • 3.1.3 使用 np.ones() 创建
                • 3.1.4 np.arange()
                • 3.1.5 np.linspace()
                • 3.1.6 np.random.random()
                • 3.1.7 np.random.normal(mu, sigma, len)
              • 3.2 读取
                • 3.2.1 元组索引
                • 3.2.2 普通多维列表方式
              • 3.3 统计运算
                • 3.3.1 求最大值
                • 3.3.2 求最小值
                • 3.3.3 求和
                • 3.3.4 求均值
                • 3.3.5 求标准差
                • 3.3.6 求中位数
              • 3.4 为什么要使用 numpy 多维数组
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档