大话Numpy(一)数组——升级的List

摘要

实例为导向,用一种简单易懂的方式介绍Numpy。笔者直接将numpy的方法写入目录,便于查询。

参考文档:

  • https://numpy.org/doc/stable/user/index.html
  • https://numpy.org/doc/stable/user/absolute_beginners.html
  • https://edu.csdn.net/job/pythonbe_02/python-3-195

To:入门Numpy的新手、回顾Numpy的老玩家、急需使用Numpy却无时间系统学习的科研人员



1、入门知识点

1.1、常量

  • nan 和Js中的nan一样,只需要注意nan不等于任何数包括它自己
  • inf 无穷大
  • pi 圆周率
  • e 自然常数

这里得注意的是它们有不同的出现方式,比如:inf Inf inf infty Infinity PINF都表示正无穷

1.2、数据类型

numpy 的数值类型实际上是 dtype 对象的实例
每个内建类型都有一个唯一定义它的字符代码,如下:

字符类型代码
bboolean‘b1’
isigned integer‘i1’, ‘i2’, ‘i4’, ‘i8’
uunsigned integer‘u1’, ‘u2’ ,‘u4’ ,‘u8’
ffloating-point‘f2’, ‘f4’, ‘f8’
ccomplex floating-point
mtimedelta64 表示两个时间之间的间隔
Mdatetime64 日期时间类型(下有细分)
Oobject
S(byte-)string S3表示长度为3的字符串
UUnicode Unicode 字符串
Vvoid
a = np.dtype('i8')
print(a.type)  # <class 'numpy.int64'>
print(a.itemsize)  # 8

值得注意的是python的整数是灵活扩容的,而numpy中的整数是会溢出的

2、实操

2.1、数组创建

ndarray是python中List的扩展,是numpy中最重要的数据结构。

array

直接将输入的列表转化为nupy.ndarray类型

asarray

array()asarray()都可以将结构数据转化为 ndarray,主要区别就是当输入是ndarray 时,array()仍然会 copy 出一个副本,占用新的内存,但不改变 dtype 时 asarray()不会。

fromfunction

依据函数和提供的散点维度取出对应坐标

参数

function 函数

shape 散点维度(x,y)在这里插入图片描述

**kwargs 一般传入dtype=数据类型

def f(x, y):
    return 2 * x + y
x = np.fromfunction(f, (3, 4), dtype=int)
print(x)
# [[0. 1. 2. 3.]
# [2. 3. 4. 5.]
# [4. 5. 6. 7.]]

zeros、ones、empty、full

这部分的加上like表示填充一个和输入同维度的数组
如用零填充,zeros_like就是创建输入数组的维度并填入0

x = np.zeros(5)
print(x)  # [0. 0. 0. 0. 0.]
x = np.zeros([2, 3])
print(x)
# [[0. 0. 0.]
#  [0. 0. 0.]]

x = np.full(2, 3)
print(x)
# [3 3]

x = np.full((2, 7), 3)
print(x)
# [[3 3 3 3 3 3 3]
#  [3 3 3 3 3 3 3]]

eye、identity

填充一个单位阵,identity表示返回一个方的

diag

提取或者构造对角数组

x = np.arange(9).reshape((3, 3))
print(x)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]
print(np.diag(x))  # [0 4 8]
print(np.diag(x, k=1))  # [1 5]
print(np.diag(x, k=-1))  # [3 7]

v = [1, 2, 3, 4]
x = np.diag(v)
print(x)
# [[1 0 0 0]
#  [0 2 0 0]
#  [0 0 3 0]
#  [0 0 0 4]]

arrange、linspace、logspace、random.rand

给定数值范围创建ndarray

def arange([start,] stop[, step,], dtype=None)
# 起、止、步长
def linspace(start, stop, num=50, endpoint=True,retstep=False, dtype=None,axis=0)
# 起、止、数量
def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0)
# 以对数刻度的返回
def rand(d0, d1, ..., dn)

2.2、切片和索引

首先得明白,numpy中的数组在做赋值运算时,返回结果是视图而不是副本。不明白视图和副本分别是什么?看看下面这个代码的运行结果就知道了:

x = np.array([1, 2, 3])
y = x
y[0] = -1
print(x)
# [-1  2  3]
print(y)
# [-1  2  3]

其余的我想也不必多说,与python的列表是一致的。
另外,numpy可以使用...来表示足够的冒号。
如一个5维数组x中,x[4,...,5,:] 等于 x[4,:,:,5,:]的含义是一致的。

x = np.array([[11, 12, 13, 14, 15],
              [16, 17, 18, 19, 20],
              [21, 22, 23, 24, 25],
              [26, 27, 28, 29, 30],
              [31, 32, 33, 34, 35]])
r = np.array([[0, 1], [3, 4]])
print(x[r])
# [[[11 12 13 14 15]
#   [16 17 18 19 20]]
#
#  [[26 27 28 29 30]
#   [31 32 33 34 35]]]

y = x > 25
print(y)
# [[False False False False False]
#  [False False False False False]
#  [False False False False False]
#  [ True  True  True  True  True]
#  [ True  True  True  True  True]]
print(x[x > 25])
# [26 27 28 29 30 31 32 33 34 35]

2.3、数组遍历

apply_along_axis

第一个参数是需要执行的函数,第二个参数表示执行的维度

y = np.apply_along_axis(np.sum, 0, x)
print(y)  # [105 110 115 120 125]
y = np.apply_along_axis(np.sum, 1, x)
print(y)  # [ 65  90 115 140 165]

2.4、数组变形1

变形

  • numpy.ndarray.shape表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩)。

  • numpy.ndarray.flat 将数组转换为一维的迭代器,可以用for访问数组每一个元素。

  • numpy.ndarray.flatten([order='C']) 将数组的副本转换为一维数组,并返回。(ravel可以返回视图)

    • order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
    • order:{'C / F,'A,K},可选使用此索引顺序读取a的元素。'C’意味着以行大的C风格顺序对元素进行索引,最后一个轴索引会更改F表示以列大的Fortran样式顺序索引元素,其中第一个索引变化最快,最后一个索引变化最快。请注意,'C’和’F’选项不考虑基础数组的内存布局,仅引用轴索引的顺序.A’表示如果a为Fortran,则以类似Fortran的索引顺序读取元素在内存中连续,否则类似C的顺序。“ K”表示按照步序在内存中的顺序读取元素,但步幅为负时反转数据除外。默认情况下,使用Cindex顺序。
  • numpy.reshape(a, newshape[, order='C'])在不更改数据的情况下为数组赋予新的形状。

  • numpy.transpose(a, axes=None) 转置

  • numpy.newaxis = None如果输入数据达不到指定的维度时,可以使用newaxis参数来增加一个维度

x = np.array([1, 2, 9, 4, 5, 6, 7, 8])
print(x.shape)  # (8,)
print(x)  # [1 2 9 4 5 6 7 8]

y = x[np.newaxis, :]
print(y.shape)  # (1, 8)
print(y)  # [[1 2 9 4 5 6 7 8]]

y = x[:, np.newaxis]
print(y.shape)  # (8, 1)
print(y)
# [[1]
#  [2]
#  [9]
#  [4]
#  [5]
#  [6]
#  [7]
#  [8]]

  • numpy.squeeze(a, axis=None) 从数组的形状中删除单维度条目。

拼接

  • numpy.concatenate((a1, a2, ...), axis=0, out=None) 连接两个数组
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[7, 8, 9], [10, 11, 12]])
z = np.concatenate([x, y])
print(z)
# [[ 1  2  3]
#  [ 4  5  6]
#  [ 7  8  9]
#  [10 11 12]]
z = np.concatenate([x, y], axis=0)
print(z)
# [[ 1  2  3]
#  [ 4  5  6]
#  [ 7  8  9]
#  [10 11 12]]
z = np.concatenate([x, y], axis=1)
print(z)
# [[ 1  2  3  7  8  9]
#  [ 4  5  6 10 11 12]]
  • numpy.stack(arrays, axis=0, out=None)增加维度的拼接
x = np.array([1, 2, 3])
y = np.array([7, 8, 9])
z = np.stack([x, y])
print(z.shape)  # (2, 3)
print(z)
# [[1 2 3]
#  [7 8 9]]

z = np.stack([x, y], axis=1)
print(z.shape)  # (3, 2)
print(z)
# [[1 7]
#  [2 8]
#  [3 9]]

  • numpy.vstack(tup)
    numpy.hstack(tup)垂直和水平方向的拼接。在数据维度等于1时,比较特殊。而当维度大于或等于2时,它们的作用相当于concatenate,用于在已有轴上进行操作。
  • numpy.tile(A, reps)将A作为子矩阵拼接成reps形状
  • numpy.repeat(a, repeats, axis=None)
x = np.array([[1, 2], [3, 4]])
y = np.repeat(x, 2)
print(y)
# [1 1 2 2 3 3 4 4]
y = np.repeat(x, 2, axis=1)
print(y)
# [[1 1 2 2]
#  [3 3 4 4]]

y = np.repeat(x, [2, 3], axis=0)
print(y)
# [[1 2]
#  [1 2]
#  [3 4]
#  [3 4]
#  [3 4]]

y = np.repeat(x, [2, 3], axis=1)
print(y)
# [[1 1 2 2 2]
#  [3 3 4 4 4]]

拆分

  • numpy.split(ary, indices_or_sections, axis=0)
  • numpy.vsplit(ary, indices_or_sections)
  • numpy.hsplit(ary, indices_or_sections)
x = np.array([[11, 12, 13, 14],
              [16, 17, 18, 19],
              [21, 22, 23, 24]])
y = np.split(x, [1, 3])
print(y)
# [array([[11, 12, 13, 14]]), array([[16, 17, 18, 19],
#        [21, 22, 23, 24]]), array([], shape=(0, 4), dtype=int32)]

y = np.split(x, [1, 3], axis=1)
print(y)
# [array([[11],
#        [16],
#        [21]]),
# array([[12, 13],
#        [17, 18],
#        [22, 23]]), 
# array([[14],
#        [19],
#        [24]])]

  1. 参考自之前学习的笔记,有大量当时应该是复制的,暂时没找到出处,特此说明。不过可能原作是英文,那就算是翻译吧哈哈 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值