Numpy 数据类型及数组基础

numpy概述

  • NumPy是Python中科学计算的基础包。
  • 它是⼀个Python库
  • 提供多维数组对象,各种派⽣对象(如掩码数组和矩阵
  • 提供对数据/数组各种操作

数据类型

  • numpy的数据类型和c语⾔中的数据类型实现并不⼀样
  • 可以理解对基础数据类型的优化和升级
  • ⼀切为了快速处理⼤型/⼤量数据为宗旨

基础数据类型

  • bool_: 布尔值,⽤⼀个字节存储
  • int_: 默认整型,通常是int64/int32
  • intc: 整型,通常是int32/int64
  • intp: ⽤作索引的整型,通常是int32/int64
  • int8/16/32/64: 整型
  • uint8/16/32/64: ⽆符号整型
  • float_: float64的简写
  • float16: 半精度浮点型, 1bit符号, 5bits指数,10bits尾数
  • float32: 单精度浮点型, 1bit符号,8bits指数,23bits尾数
  • float64: 双精度浮点型, 1bit符号,11bits指数,52bits尾数
  • complex_: complex128
  • complex64: 复数,两个32位浮点数表示
  • complex128: 复数, 由两个64位浮点数表示

简写型数据类型

  • ‘b’: 字节型, np.dtype(‘b’)
  • ‘i’: 有符号整型, np.dtype(‘i4’)就是⼀个 np.int32类型
  • ’u’: ⽆符号整型, np.dtype(‘u8’)就是⼀个np.uint64
  • ‘f’: 浮点型, np.dtype(‘f8’)
  • ‘c’: 复数浮点型
  • ’S’: ‘a’: 字符串, np.dtype(‘S6’)
  • ‘U’: Unicode编码字符串, n’p.dtype(‘U’) 就是np.str_类型
  • ‘V’: 原⽣数据, ⽐如空或者void, np.dtype(‘V’)就是np.void

其中如果出现<则表示低字节序(little endian), 同理>则表示⾼字节序

numpy数组基础

  • 数组操作是numpy的核⼼
  • 数组跟list类似,但数组要求内容类型必须⼀致,如果不⼀致需要进⾏强制转换,可能会损失精度。相当于是一个拓展的列表。
  • 主要包括
    • 数组的属性
    • 数组的索引
    • 数组的切分
    • 数组的编写
    • 数组的拼接和分裂

数组的属性

  • numpy可以有多维数组
  • 其属性包括:
    • 维度(ndim):一维、二维、三维
    • 形状(shape):通常可以理解成数组各个维度的⻓度
    • ⻓度(size): 数组所存储的元素的总个数
    • 数据类型(dtype): 数组的数据类型(数组要求数据必须同⼀类型)
    • itemsize: 每个元素的字节⻓度
    • nbytes: nbytes=itemsize x size

下面是一个数组的例子

import numpy as np
# ⽣成三个数组
a1 = np.random.randint(100, size=10) # 参数siz是⽣成数组的shape属性
a2 = np.random.randint(100, size=(4,6))
a3 = np.random.randint(100, size=(2,5,6))
# 打印出数组a1, a2, a3的属性
for a in [a1, a2, a3]:
 print("dtype={}, ndim={}, shape={}, size={}, itemsize={}, nbytes={}".\
 format(a.dtype, a.ndim, a.shape, a.size, a.itemsize, a.nbytes))
dtype=int32, ndim=1, shape=(10,), size=10, itemsize=4, nbytes=40
dtype=int32, ndim=2, shape=(4, 6), size=24, itemsize=4, nbytes=96
dtype=int32, ndim=3, shape=(2, 5, 6), size=60, itemsize=4, nbytes=240

几个特殊数组的创建

import numpy as np
x = np.empty(5)
print("Empty array: \n", x)
x = np.zeros(10)
print("Zeros Array: \n", x)
x = np.ones(10)
print("Ones Array: \n", x)
Empty array:
 [-4.94065646e-323 0.00000000e+000 2.12199579e-314 0.00000000e+000
 0.00000000e+000]
Zeros Array:
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
Ones Array:
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

这个empty和我们理解的空稍微有所差别,他是一些及其接近0的数。而zeros则是直接都为0。

数组的索引

  • 数组的索引使⽤⽅式跟list⼀样。可以是正数,负数

一维数组的索引

# ⼀位数组的索引
a1 = np.random.randint(100, size=10)
print('a1=', a1)
# 数组的索引跟list⼀致,分正负数,意义和⽤法都与list⼀致
print("a1[1]=", a1[1])
print("a1[-1]=", a1[-1])
a1={} [55 66 85 75 27 31 18 8 6 73]
a1[1]= 66
a1[-1]= 73

多维数组的索引

# 多维数组需要使⽤逗号隔开,其余使⽤⽅法和list类似
a1 = np.random.randint(100, size=(3,5))
print("a1 = ", a1)
# # 数组的索引跟list⼀致,分正负数,意义和⽤法都与list⼀致
# 得到⼆维数组的某⼀⾏
print("a1[1] = ", a1[1])
print("a1[1] = ", a1[1, :])
print("a1[-2] = ", a1[-2])
# 得到⼆维数组的某⼀列
print("a1[:,1] = ", a1[:,1])
# 得到⼆维数组的某⼀个元素
print("a1[2,2] =" , a1[2,2])
print("a1[-1,-2] = ", a1[-1,-2])
a1 = [[97 1 65 92 81]
 [40 75 66 53 53]
 [34 56 63 64 92]]
a1[1] = [40 75 66 53 53]
a1[1] = [40 75 66 53 53]
a1[-2] = [40 75 66 53 53]
a1[:,1] = [ 1 75 56]
a1[2,2] = 63
a1[-1,-2] = 64

数组的切片

  • 数组的切⽚功能和使⽤同list基本⼀致
  • 数组的切⽚产⽣的是数据的视图⽽不是副本,及切⽚后的数据和源数据是⼀份
  • 基本⽤法是 x[start : stop : step] 三个参数决定切⽚的结果,有些可省略
    • start=0
    • stop=维度⼤⼩
    • step=1

⼀维数组的切片

⼀维数组跟list使⽤⽅法⼀致

# 定义⼀维数组
import numpy as np
a = np.arange(1, 11)
print("a = ", a)
# 获取中间元素
print("a[3:7] = ", a[3:7])
# 获取偶数
print("a[1::2] = ", a[1::2])
# 获取前五个元素
print("a[:5] = ", a[: 5])
# 获取后五个元素
print("a[5:] = ", a[5:])
# 后五个元素倒序
print("a[:-6:-1] = ", a[:-6:-1])
a = [ 1 2 3 4 5 6 7 8 9 10]
a[3:7] = [4 5 6 7]
a[1::2] = [ 2 4 6 8 10]
a[:5] = [1 2 3 4 5]
a[5:] = [ 6 7 8 9 10]
a[:-6:-1] = [10 9 8 7 6]

多维数组的切片

  • 多维数组的切⽚跟list逻辑⼀致
  • 使用方法上可以看作多维的list
# 定义多维数组
a = np.random.randint(10, size=(3,5))
#打印出a
print("a = ", "\n", a)
# 截取多维数组的⼀段
print("a[1:4, 1:4] = \n", a[1:4, 1:4])
# step参数也可以是负数,标识逆序
print("a[1:4:-1, 1:4:-1] = ", a[1:4:-1, 1:4:-1])
print("a[1:4:-1, 1:4:-1] = \r\n", a[::-1, ::-1])
a =
 [[1 8 5 3 3]
 [6 3 8 3 9]
 [8 9 5 2 5]]
a[1:4, 1:4] =
 [[3 8 3]
 [9 5 2]]
a[1:4:-1, 1:4:-1] = []
a[1:4:-1, 1:4:-1] =
 [[5 2 5 9 8]
 [9 3 8 3 6]
 [3 3 5 8 1]]
  • 获取数组的单⾏或者单列是⼀种常⻅操作,可以利⽤索引和切⽚技术实现这个功能。
  • 处于语法简洁考虑,空的切⽚可以省略
# 利⽤上⾯
# 定义多维数组
a = np.random.randint(10, size=(3,5))
print("a = \n", a)
# 得到第⼆⾏
print("a[1, :] = ", a[1,:])
# 得到倒序的第⼆列
print("a[::-1, 1] = ", a[::-1, 1])
# 空的切⽚可以省略
# a[0, :]可以省略
print("a[0] = ", a[0])
a =
 [[1 5 1 7 0]
 [8 3 4 0 6]
 [1 2 6 9 5]]
a[1, :] = [8 3 4 0 6]
a[::-1, 1] = [2 3 5]
a[0] = [1 5 1 7 0]

数组切片产生的视图和副本

  • 数组切⽚和list切⽚不同之处是,数组切⽚的结果是源数据的视图而不是副本
  • 如果想要产⽣源数据的副本,需要⽤到copy函数
# 证明数组切⽚产⽣的是视图⽽不是副本
# 1. 产⽣⼀个数组
a1 = np.zeros(shape=(3,5))
print("a1 = ",a1)
# 2. 切⽚产⽣新数组
a2 = a1[1:, 1:4]
# 3, 修改切⽚后数组内容
a2[1, 2] = 99
# 4. 查看结果
print("a1 = \n", a1)
print("a2 = \n", a2)
# 5. 结果证明,仅仅修改切⽚后数据,源数据也发⽣了改变
# 说明,切⽚仅仅是视图⽽不是数据的副本
a1 = [[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
a1 =
 [[ 0. 0. 0. 0. 0.]
 [ 0. 0. 0. 0. 0.]
 [ 0. 0. 0. 99. 0.]]
a2 =
 [[ 0. 0. 0.]
 [ 0. 0. 99.]]

如果需要产⽣数据的副本,需要会用到copy功能

# 1. 产⽣⼀个数组
a1 = np.zeros(shape=(3,5))
print("a1 = ",a1)
# 2. 切⽚产⽣新数组,同时使⽤copy产⽣⼀个数据副本
a2 = a1[1:, 1:4].copy()
# 3, 修改切⽚后数组内容
a2[1, 2] = 99
# 4. 查看结果
print("a1 = \n", a1)
print("a2 = \n", a2)
a1 = [[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
a1 =
 [[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
a2 =
 [[ 0. 0. 0.]
 [ 0. 0. 99.]]

数组的变形

  • 变形可以通过reshape来进⾏操作,前提是必须前后⻓度⼀致
  • 也可以通过newaxis关键字来完成
    • newaxis是⼀个NoneType的内容,其实就是None
    • ⼀般用来标识⼀给新的维度,比如1维的数组想变形成⼆维的,需要单纯的增加⼀个维度
    • 比如 shape=(3,) ==> shape=(3,1)
# shape的使⽤
# 需要注意数组的⻓度前后必须⼀致,此处 9=3x3
# 同时需要注意shape的参数是数组,不是⼏个整数参数
a = np.arange(1,10).reshape((3,3))
print("a = \n", a)
print("a.shape = ", a.shape)
a =
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
a.shape = (3, 3)
# newaxis 是单纯的增加⼀个维度
a = np.arange(10)
print("a = ", a)
print("a.shape = ", a.shape)
# 获得⼀个⾏向量
a1 = a[np.newaxis, :]
print("a1 = ", a1)
print("a1.shape = ", a1.shape)
# 获得⼀个列向量
a2 = a[:, np.newaxis]
print("a2 = ", a2)
print("a2.shape = ", a2.shape)
a = [0 1 2 3 4 5 6 7 8 9]
a.shape = (10,)
a1 = [[0 1 2 3 4 5 6 7 8 9]]
a1.shape = (1, 10)
a2 = [[0]
 [1]
 [2]
 [3]
 [4]
 [5]
 [6]
 [7]
 [8]
 [9]]
a2.shape = (10, 1)

数组的拼接和分裂

现在要研究如何把多个数组拼接成⼀个数组或者把⼀个数组拆分成多个数组的情况。

现在开始需要注意维度的概念或者轴的概念,我们在对数组进⾏拼接的时候需要明确

沿着哪个轴进⾏拼接,以⼆维数组为例,这⾥竖轴作为第⼀个轴,索引值为0,横轴作为第⼆个轴,索引值为1,如果默认的拼接,则默认沿着0轴。

数组的拼接

对数组的拼接⼀般默认前提是可以进⾏拼接,比如3x3的数组和5x5的数组拼接就可能存在问题,因为⼆者需要

拼接的维度是数值不等,此时强⾏拼接除⾮进⾏自动补齐缺失的值。

数组的拼接⼀般需要指明沿着哪个轴进⾏拼接,具体实现主要由下⾯几个函数完成:

  • numpy.concatenate: 可以指明拼接的轴
  • numpy.hstack: 沿着横轴进⾏拼接
  • numpy.vstack: 沿着竖轴进⾏拼接
  • numpy.dstack: 沿着第三个轴进⾏拼接
    下面三个函数其实可以看做是 numpy.concatenate 的特例,运用 numpy.concatenate 也同样可以完成
# concatenate
# 对⼀维数组的拼接
# ⽣成数组a1, a2后将两个数组拼接成a3
# 此处拼接是⾃⼰在后⾯⾃动追加
a1 = np.arange(5)
a2 = np.arange(5, 10)
a3 = np.concatenate([a1, a2])
# concatenate可以⼀次性链接好⼏个数组
a4 = np.concatenate([a1, a2, a3])
print("a1 = ", a1)
print("a2 = ", a2)
print("a3 = ", a3)
print("a4 = ", a4)
a1 = [0 1 2 3 4]
a2 = [5 6 7 8 9]
a3 = [0 1 2 3 4 5 6 7 8 9]
a4 = [0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
# 同样,concatenate可以对多维数组进⾏拼接
# 拼接的时候,往往需要指出沿着哪个轴或者维度进⾏拼接
a1 = np.arange(12).reshape((3,4))
print("a1 = \n", a1)
a2 = np.arange(100,112).reshape((3,4))
print("a2 = \n", a2)
# 此时明显看出concatenate默认是沿着第⼀个轴(index=0,即竖轴)拼接
a3 = np.concatenate([a1, a2])
print("a3 = \n", a3)
# 如果有必要,需要指明进⾏拼接的轴
# 下⾯案例沿着第⼆个轴(即横轴)进⾏拼接,index=1
a4 = np.concatenate([a1, a2], axis=1)
print("a4 = \n", a4)
a1 =
 [[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]]
a2 =
 [[100 101 102 103]
 [104 105 106 107]
  [108 109 110 111]]
a3 =
 [[ 0 1 2 3]
 [ 4 5 6 7]
 [ 8 9 10 11]
 [100 101 102 103]
 [104 105 106 107]
 [108 109 110 111]]
a4 =
 [[ 0 1 2 3 100 101 102 103]
 [ 4 5 6 7 104 105 106 107]
 [ 8 9 10 11 108 109 110 111]]

沿着指定的横轴或者竖轴进行拼接可以直接是vstack或者hstack,相对简洁

# vstack & hstack
a1 = np.arange(4).reshape((1,4))
a2 = np.arange(100,112).reshape((3,4))
a3 = np.arange(10,13).reshape((3, 1))
# 注意vstack参数的shape
a4 = np.vstack([a1, a2])
print("a4 = \n", a4)
a5 = np.hstack([a2, a3])
print("a5 = \n", a5)
a4 =
 [[ 0 1 2 3]
 [100 101 102 103]
 [104 105 106 107]
 [108 109 110 111]]
a5 =
 [[100 101 102 103 10]
 [104 105 106 107 11]
 [108 109 110 111 12]]

数组的分裂

数组的分裂研究的是如何把⼀个数组分割成多个数组。
主要有⼀下⼏个函数完成:

  • numpy.split: 默认沿着axis=0进行分裂,可以指定轴向
  • numpy.hsplit: 沿着横轴进行分裂
  • numpy.vsplit: 沿着竖轴进行分裂
# ⽣成⼀个6x8的数组
a1 = np.arange(48).reshape((6,8))
print("a1 = \n", a1)
print("-" * 30)
# 沿着0轴进⾏分裂成两部分
a2, a3 = np.split(a1, [3])
print("a2 = \n", a2)
print("-" * 30)
print("a3 = \n", a3)
print("-" * 30)
# 沿着0轴分裂成三部分
a4, a5, a6 = np.split(a1, [2,4])
print("a4 = \n", a4)
print("-" * 30)
print("a5 = \n", a5)
print("-" * 30)
print("a6 = \n", a6)
print("-" * 30)
# 沿着1轴分裂成三部分
a7, a8, a9 = np.split(a1, [2,5], axis=1)
print("a7 = \n", a7)
print("-" * 30)
print("a8 = \n", a8)
print("-" * 30)
print("a9 = \n", a9)
a1 =
 [[ 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 25 26 27 28 29 30 31]
 [32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47]]
------------------------------
a2 =
 [[ 0 1 2 3 4 5 6 7]
 [ 8 9 10 11 12 13 14 15]
 [16 17 18 19 20 21 22 23]]
------------------------------
a3 =
 [[24 25 26 27 28 29 30 31]
 [32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47]]
------------------------------
a4 =
 [[ 0 1 2 3 4 5 6 7]
  [ 8 9 10 11 12 13 14 15]]
------------------------------
a5 =
 [[16 17 18 19 20 21 22 23]
 [24 25 26 27 28 29 30 31]]
------------------------------
a6 =
 [[32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47]]
------------------------------
a7 =
 [[ 0 1]
 [ 8 9]
 [16 17]
 [24 25]
 [32 33]
 [40 41]]
------------------------------
a8 =
 [[ 2 3 4]
 [10 11 12]
 [18 19 20]
 [26 27 28]
 [34 35 36]
 [42 43 44]]
------------------------------
a9 =
 [[ 5 6 7]
 [13 14 15]
 [21 22 23]
 [29 30 31]
 [37 38 39]
 [45 46 47]]

类似hstack之类的, vsplit,hsplit,dsplit是沿着0轴,1轴,2轴分裂的缩写

a = np.arange(20).reshape([4,5])
print("a = \n", a)
# vsplit
a1, a2 = np.vsplit(a, [2])
print("a1 = \n", a1)
print("a2 = \n", a2)
# hsplit
a3, a4, a5 = np.hsplit(a, [2,4])
print("a3 = \n", a3)
print("a4 = \n", a4)
print("a5 = \n", a5)
a =
 [[ 0 1 2 3 4]
 [ 5 6 7 8 9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
a1 =
 [[0 1 2 3 4]
 [5 6 7 8 9]]
a2 =
 [[10 11 12 13 14]
 [15 16 17 18 19]]
a3 =
 [[ 0 1]
 [ 5 6]
 [10 11]
 [15 16]]
a4 =
 [[ 2 3]
 [ 7 8]
 [12 13]
 [17 18]]
a5 =
 [[ 4]
 [ 9]
 [14]
 [19]]

你可能感兴趣的:(Numpy简单入门)