Numpy学习——Numpy初探

Numpy&Numpy arrays

Numpy arrays

  1. Python对象

    高级数字对象,包含整数、浮点类型;
    低成本的插入和添加数据以及快速查找功能。

  2. Numpy提供:

    多维数组支持;
    贴近硬件底层(效率);
    为科学计算设计(方便);
    面向数组计算。

>>> import numpy as np
>>> a = np.array([0, 1, 2, 3])
>>> a
array([0, 1, 2, 3])

例如,一个array包含:

  • 仿真和实验过程中离散时间的数值
  • 通过测量装置记录信号内容,例如声波信号
  • 图像的像素,灰度或颜色
  • 再不同坐标系下测量的3D数据,核磁共振扫描

Numpy再数值处理上表现高效的性能

In [1]: L = range(1000)
In [2]: %timeit [i**2 for i in L]
1000 loops, best of 3: 403 us per loop
In [3]: a = np.arange(1000)
IN [4]: %timeit a**2
100000 loops, best of 3: 12.7 us per loop

可以看出执行同样的平方操作,numpy的速度明显更快

NumPy参考文档

Numpy Doc
也可以利用numpy自带的交互帮助,或者np.lookfor(’ ’ )

Import约定

导入numpy包常用的语法约定:

import numpy as np

创建arrays

手动构造arrays

  1. 1-D:
>>> a = np.array([0, 1, 2, 3])
>>> a
array([0, 1, 2, 3])
>>> a.ndim
1
>>> a.shape
(4,)
>>> len(a)
4
  1. 2-D, 3-D, ···
>>> b = np.array([[0, 1, 2], [3, 4, 5]])    # 2 x 3 array
>>> b
array([[0, 1, 2],
	   [3, 4, 5]])
>>> b.ndim
2
>>> b.shape
(2, 3)
>>> len(b)    # returns the size of the first dimension
2
>>> c = np.array([[[1], [2]], [[3], [4]]])
>>> c
array([[[1], 
		[2]], 
	   [[3], 
	    [4]]])
>>> c.shape
(2, 2, 1)

函数创建arrays

实际上,我们几乎不一个一个输入

  1. 均匀分布
>>> a = np.arange(10) # 0 .. n-1  (!)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = np.arange(1, 9, 2) # start, end (exclusive), step
>>> b
array([1, 3, 5, 7])
>>> c = np.linspace(0, 1, 6) # start, end, num-points
>>> c
array([0., 0.2, 0.4, 0.6, 0.8, 1. ])
>>> d = np.linspace(0, 1, 5, endpoint=False)
>>> d
array([0. , 0.2, 0.4, 0.6, 0.8])
  1. 常见数组
>>> a = np.ones((3, 3))  # reminder: (3, 3) is a tuple
>>> a
array([[1., 1., 1.],
	   [1., 1., 1.],
	   [1., 1., 1.]])
>>> b = np.zeros((2, 2))
>>> b
array([[0., 0.],
	   [0., 0.]])
>>> c = np.eye(3)
>>> c
array([[1., 0., 0.],
	   [0., 1., 0.],
	   [0., 0., 1.]])
>>> d = np.diag(np.array([1, 2, 3, 4]))
>>> d
array([[1, 0, 0, 0],
	   [0, 2, 0, 0],
	   [0, 0, 3, 0],
	   [0, 0, 0, 4]])
  1. 随机数组
>>> a = np.random.rand(4)  # uniform in [0, 1]
>>> a
array([ 0.95799151, 0.14222247, 0.08777354, 0.51887998])
>>> b = np.random.randn(4)  # Gaussian
>>> b
array([ 0.37554699, -0.11425369, -0.47616538, 1.79664113])
>>> np.random.seed(1234)  # Setting the random seed

基本数据类型(basic data types)

你可能会注意到,在一些例子中,被显示的数组元素后面尾随一个点(例如2.)。这是由于不同的数据类型所导致的:

>>> a = np.array([1, 2, 3])
>>> a.dtype
dtype('int64')
>>> b = np.array([1., 2., 3.])
>>> b.dtype
dtype('float')

不同的数据类型允许我们在内存中更紧凑的存储,但是多数时候我们只使用浮点数。值得注意的是,在以上的例子中,numpy自动从输入中检测数据类型。
你可以直接显示指定你想要的数据类型:

>>> c = np.array([1, 2, 3], dtype=float)
>>> c.dtype
dtype('float')

默认数据类型是浮点型

>>> a = np.ones((3, 3))
>>> a.dtype
dtype('float')

其他的数据类型:

关键字类型
complex复数
bool布尔
strings字符串
int32
int64
整数
uint32
uint64
无符号整数

可视化(visualization)

现在我们有了我们的第一个数据数组,我们要来将 它们可视化。
matpotlib是一个2D绘图包,我们可以import它的函数如下:

>>> import matplotlib.pyplot as plt  # the tidy war

接下来使用

>>> plt.plot(x, y)
>>> plt.show()
  1. 1D绘图
>>> x = np.linspace(0, 3, 20)
>>> y = np.linspace(0, 9, 20)
>>> plt.plot(x, y)         # line plot
>>> plt.plot(x, y, 'o')    # dot plot
>>> plt.show()

在这里插入图片描述

  1. 2D绘图
>>> image = np.random.rand(30, 30)
>>> plt.imshow(image, cmap=plt.cm.hot)
>>> plt.colorbar()
>>> plt.show()

索引(indexing) &切片(slicing)

数组中的某一项可以像python其他序列(例如list)一样被直接索引:

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

索引从0开始,像其他的python序列。相反在matlab中索引从1开始。
支持python常用的反转序列方法:

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

对于多维数组,索引是元组或者整数:

>>> a = np.diag(np.arange(3))
>>> a
array([[0, 0, 0],
	   [0, 1, 0],
	   [0, 0, 2]])
>>> a[1, 1]
1
>>> a[2, 1] = 10
>>> a
array([[ 0,  0,  0],
       [ 0,  1,  0],
       [ 0, 10,  2]])
>>> a[1]
array([0, 1, 0])

注意
在二维数组中,第一维度是行,第二是列
对于多维数组a,a[0]是通过取出所有未指定维度的元素

数组也可以像python其他的序列一样被切片:

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

注意,最后一个索引并不被包含:

>>> a[:4]
array([0, 1, 2, 3])

三个索引值都不是必须的:start默认值是0,end默认值是最后一位,step默认值是1:

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

关于numpy索引和切片的一个小的说明

在这里插入图片描述
也可以结合赋值和切片:

>>> a = np.arange(10)
>>> a[5:] = 10
>>> a
array([0, 1, 2, 3, 4, 10, 10, 10, 10, 10])
>>> b = np.arange(5)
>>> a[5:] = b[::-1]
>>> a
array([0, 1, 2, 3, 4, 4, 3, 2, 1, 0])

复制(copy) & 视图(view)

一个切片操作在原始数组上生成一个视图,这只是访问数据数组的一种方式。因此原始数组并没有在内存中拷贝,你可以使用np.may_share_memory()来检查是否有两个数组共享同一块内存块。注意,可能会有warning。
当你修改视图的时候,原始数组也会发生修改:

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = a[::2]
>>> b
array([0, 2, 4, 6, 8])
>>> np.may_share_memory(a, b)
True
>>> b[0] = 12
>>> b
array([12, 2, 4, 6, 8])
>>> a   # (!)
array([12, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a = np.arange(10)
>>> c = a[::2].copy()  # force a copy
>>> c[0] = 12
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.may_share_memory(a, c)
False

乍一看,这种行为可能令人吃惊,但它可以节省内存和时间。

应用举例:

在这里插入图片描述
计算0~99之间的质数,

  • 构造一个(100,)布尔数组is_prime, 填充成True:
>>> is_prime = np.ones((100,), dtype=bool)
  • 去掉不是质数的0和1:
>>> is_prime[:2] = 0
  • 对于每一个从2开始的整数j,划掉更高的倍数```
>>> N_max = int(np.sqrt(len(is_prime) - 1))
>>> for j in range(2, N_max + 1):
		is_prime[2*j::j] = False
  • 在上述操作以后,is_prime中的True就是我们要的质数,遍历即可。

花式索引(fancy indexing)

Numpy数组可以被索引通过切片,也可以通过布尔和整数数组(masks)。这种方法被称作fancy indexing。它生成copies而不是views。

使用布尔数组

>>> np.random.seed(3)
>>> a = np.random.randint(0, 21, 15)
>>> a
array([10, 3, 8, 0, 19, 10, 11, 9, 10, 6, 0, 20, 12, 7, 14])
>>> (a % 3 == 0)
array([False, True, False, True, False, False, False, True, False, True, True, False, True, False, False])
>>> mask = (a % 3 == 0)
>>> extract_from_a = a[mask]
>>> extract_from_a
array([3, 0, 9, 6, 0, 12])

在赋值一个新的值到子数组的时候,使用数组索引非常有用:

>>> a[a % 3 == 0] = -1
>>> a
array([10, -1, 8, -1, 19, 10, 11, -1, 10, -1, -1, 20, -1, 7, 14])

使用整数数组索引

>>> a = np.arange(0, 100, 10)
>>> a
array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90])

可以用一个整数数组索引,其中相同的索引重复几次:

>>> a[[2, 3, 2, 4, 2]]  # note: [2, 3, 2, 4, 2] is a Python list
>>> a
array([20, 30, 20, 40, 20])

新的值可以被赋值通过这种索引:

>>> a[[9, 7]] = -100
>>> a
array([   0,   10,   20,   30,   40,   50,   60, -100,   80, -100,])

当一个新的数组被整数数组索引创建的时候,新的数组有和整数数组同样的形状:

>>> a = np.arange(10)
>>> idx = np.array([[3, 4], [9, 7]])
>>> idx.shape
(2, 2)
>>> a[idx]
array([[3, 4],
	   [9, 7]])

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值