【Numpy】12 数据类型和基本操作

【Numpy】12 数据类型和基本操作

2023.1.3 一口气学完Numpy

12.1 为什么用numpy

  • 矩阵运算的时候,速度快。深度学习的核心基础是矩阵运算。

Numpy 是上个时代的产物,它基本上所有的优化都是基于 CPU 的优化,而现在的深度学习,大多都要利用到 GPU 甚至是 TPU 的计算单元。 所以有很多操作,Numpy 是不擅长的。但是像 Tensorflow,Pytorch 这种深度学习库,在很大程度上都是借鉴了 Numpy 而开发的。

  • 自己开发不依赖于 Tensorflow 和 Pytorch 的深度学习的项目,建议从 Numpy 入手。(比如遗传算法)
  • TensorflowPytorch 能实现的项目,就尽量用它们开发,Numpy 在深度学习上的功能,和 GPU 的加速上,都不占优势。

12.2 Ndarray 对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray

  • ndarray 对象是用于存放同类型元素的多维数组
  • ndarray 中的每个元素在内存中都有相同存储大小的区域。

12.2.1 对象的常规操作

12.2.1.1 查看数组类型type()

import numpy as np 
a = np.array([[1,2,3],[5,12,4]])  
print (a)
[[ 1  2  3]
 [ 5 12  4]]
type(a)
numpy.ndarray

12.2.2.2 数组形状ndarray.shape

a.shape
(2, 3)

12.2.2.3 重新定义形状reshape

data = np.arange(6)
print(data)
data = np.arange(6).reshape([2, 3])
data
[0 1 2 3 4 5]





array([[0, 1, 2],
       [3, 4, 5]])

12.2.2.4 维数ndarray.ndim

a = np.arange(24)  
print (a.ndim)             # a 现只有一个维度
# 现在调整其大小
b = a.reshape(2,4,3)  # b 现在拥有三个维度
print (b.ndim)
1
3

12.2.2.5 元素类型

print(b,b.dtype)
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]]

 [[12 13 14]
  [15 16 17]
  [18 19 20]
  [21 22 23]]] int32

12.2.2 创建数组

12.2.2.1 空数组np.empty

np.empty(形状,数据类型)
数组元素为随机值,因为它们未初始化

import numpy as np 
x = np.empty([3,2], dtype = int) 
print (x)
[[        112     4522068]
 [ -952915696         414]
 [          0 -2147483648]]

12.2.2.2 零值填充numpy.zeros()

默认是浮点型float64,也可以指定类型

x = np.zeros((2,2)) 
print(x)
print(x.dtype)
[[0. 0.]
 [0. 0.]]
float64
# 设置类型为整数
y = np.zeros((5), dtype = int) 
print(y)
[0 0 0 0 0]
  • 类似的还有全1创建:numpy.ones(形状)
  • 类似的还有对角矩阵创建:numpy.eye(形状)
x = np.eye(2,2) 
print(x)
[[1. 0.]
 [0. 1.]]
# 也可以不是正的
x = np.eye(2,3) 
print(x)
[[1. 0. 0.]
 [0. 1. 0.]]

12.2.2.3 np.arange()

而创建有些规律的数据也是 Numpy 的拿手好戏。首先我要说一个最常见的,arange 功能,这就有点像 Python 里的 range 功能,用来得到一个序列,我举个例子

print("python range:", list(range(5)))
print("numpy arange:", np.arange(5))
python range: [0, 1, 2, 3, 4]
numpy arange: [0 1 2 3 4]
# (start, end, step) 
print("python range:", list(range(3, 10, 2)))
print("numpy arange:", np.arange(3, 10, 2))
python range: [3, 5, 7, 9]
numpy arange: [3 5 7 9]

12.2.2.4 np.linspace()

直译是线性空间。也就是从开始 start 到结束end均匀分布 num 个数据点,并返回

# (start, end, num)
print("linspace:", np.linspace(-1, 1, 5))
linspace: [-1.  -0.5  0.   0.5  1. ]

12.2.3 从已有的数组创建数组

12.2.3.1 将列表转换为 ndarray

import numpy as np 
 
x =  [1,2,3] 
a = np.asarray(x, dtype =  float)  
print (type(x),type(a))
 

np.asarray(x):x可以是列表、元组等转换为ndarray格式

### 12.2.3.2 np.zeros_like(), np.ones_like(), np.full_like()
- 已经有一份数据,我们想创建一个和它类型一样,大小一样的另一份数据, 可以设置类型,用已知数据的类型
data = np.array([
[1,2,3],
[4,5,6]
], dtype=np.int64)
ones = np.ones(data.shape, dtype=data.dtype)
ones
array([[1, 1, 1],
       [1, 1, 1]], dtype=int64)
  • 也我们可以调用 np.xxx_like 这种形式的功能
ones_like = np.ones_like(data)
ones_like
array([[1, 1, 1],
       [1, 1, 1]], dtype=int64)
  • np.full_like(和谁一样, 填充的数据)
print(np.zeros_like(data))
print(np.full_like(data, 6))
[[0 0 0]
 [0 0 0]]
[[6 6 6]
 [6 6 6]]

12.2.4 随机数和随机操作

12.2.4.1 np.random.rand(), np.random.random()

  • np.random.rand() 是一种最方便去生成带 shape 的 [0, 1) 之间取值的 Array。实现同一个目的的还有这样一种写法,功能上没差别,但是就是看你个人习惯了,
  • np.random.random() 用它就是直接传一个 shape 进去。
# 随机生成 [0, 1) 之间的数
dim1, dim2 = 3, 2
print(np.random.rand(dim1, dim2)) # 你还能继续添加 dim3 或更多
[[0.49989771 0.48202423]
 [0.0920152  0.80241831]
 [0.01686598 0.36143663]]
#print(np.random.random([dim1, dim2]))相当于
print(np.random.random([3, 2]))
[[0.78749328 0.9306585 ]
 [0.43213537 0.89557413]
 [0.20278646 0.75437857]]
### 12.2.4.2 np.random.randn(), np.random.randint()
- np.random.randn():按照标准正态分布去生成
- np.random.randint():随机整数,开始结尾 几个数
print(np.random.randn(dim1, dim2))
[[ 0.22624066 -0.7838529 ]
 [-0.43663436 -0.82459037]
 [ 1.2300422  -0.73857468]]
print(np.random.randint(low=-3, high=6, size=10))
[ 2 -2  1  5  4 -2  4  5  0  1]

12.2.4.3 随机从一组数选择np.random.choice()

replace=False有没有放回抽取 还是很重要的

data = np.array([2,1,3,4,6])
print("选一个:", np.random.choice(data))
print("选多个:", np.random.choice(data, size=3))
print("不重复地选多个(不放回):", np.random.choice(data, size=3, replace=False))
print("带权重地选择:", np.random.choice(data, size=10, p=[0,0,0,0.2,0.8]))
选一个: 6
选多个: [4 6 6]
不重复地选多个(不放回): [4 6 2]
带权重地选择: [4 6 6 6 6 6 6 6 6 6]
`np.random.choice(data)`:是从数据data中随机抽;`size`:选几个数;`replace=False`:不重样;`p`:抽的gailv;

12.2.4.4 将数据随机打乱np.random.shuffle()、np.random.permutation()

保持原型状

print(data)
[2 1 3 4 6]
np.random.shuffle(data)
print("shuffled:", data)
shuffled: [2 6 1 3 4]
  • np.random.shuffle()是对原有数据进行打乱。所以要保留原来数据,一般要np.copy(data) 备份一下
  • np.random.permutation(),是打乱后行程新的数据
#np.random.shuffle(data)
data_copy = np.copy(data)
np.random.shuffle(data)
print("源数据:", data_copy)
print("shuffled:", data)
源数据: [2 6 1 3 4]
shuffled: [2 6 3 1 4]
#np.random.permutation(data)
print("直接出乱序序列:", np.random.permutation(10))
data = np.arange(12).reshape([6,2])
print("多维数据在第一维度上乱序:", np.random.permutation(data))
直接出乱序序列: [6 1 5 2 7 4 9 3 0 8]
多维数据在第一维度上乱序: [[ 8  9]
 [ 6  7]
 [10 11]
 [ 2  3]
 [ 0  1]
 [ 4  5]]

12.2.4.5 随机分布 np.random.normal(), np.random.uniform()

# (均值,方差,size)
print("正态分布:", np.random.normal(1, 0.2, 10))

# (最低,最高,size)
print("均匀分布:", np.random.uniform(-1, 1, 10))
正态分布: [0.98271868 1.10408556 1.19706026 0.85296396 0.86414722 0.71507546
 0.92360382 0.87213024 1.01227216 1.02784269]
均匀分布: [ 0.44634207  0.49971606 -0.7768119  -0.59691976 -0.04761686 -0.53302451
  0.32256355  0.41130953 -0.04766905  0.97091207]

12.2.4.6 随机种子seed

随机种子一样的 运行多少次,随机出来的数都一样。要对比两种随机初始化模型的优劣,或者在强化学习中要固定随机环境的随机序列可以用到

# seed(1) 代表的就是 1 号随机序列
np.random.seed(1)
print(np.random.randint(2, 10, size=3))
print(np.random.randint(2, 10, size=3))
[7 5 6]
[2 9 3]
# seed(1) 代表的就是 1 号随机序列
#再运行一次
np.random.seed(1)
print(np.random.randint(2, 10, size=3))
print(np.random.randint(2, 10, size=3))
[7 5 6]
[2 9 3]
np.random.seed(2)
print(np.random.randint(2, 10, size=3))
np.random.seed(2)
print(np.random.randint(2, 10, size=3))
[2 9 7]
[2 9 7]

12.3 访问对象

12.3.1 直接访问

12.3.2.1 一维

a = np.array([1, 2, 3])
print("a[0]:", a[0])
print("a[1]:", a[1])
a[0]: 1
a[1]: 2

也可以同时访问多个】:访问的组成一个列表,所以多用一个[]

print(a)
print("a[[0,1]]是访问0号和1号:", a[[0,1]])
print("a[[1,1,0]]是访问1号、1号和0号:", a[[1,1,0]])
[1 2 3]
a[[0,1]]是访问0号和1号: [1 2]
a[[1,1,0]]是访问1号、1号和0号: [2 2 1]

12.3.2.2 二维或者多维数据

  • 缺项的,都是从高维算的。这个1就是高维方向的1,也就是第1
b = np.array([
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
])

# 选第 2 行所有数
print("b[1]:", b[1])   
b[1]: [5 6 7 8]
  • ②直接访问某个值
# 选第 2 行,第 1 列的数
print("b[1,0]:", b[1,0]) 
b[1,0]: 5
  • ③访问多个值
# 这个看着有点纠结,如果对应到数据,
# 第一个拿的是数据位是 [1,2]
# 第二个拿的是 [0,3]
print("b[[1,0],[2,3]]:\n", 
b[[1,0],
[2,3]])
b[[1,0],[2,3]]:
 [7 4]

12.3.2 切片访问

和python一样

b = np.array([
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
])

print("b[:2]:\n", b[:2])
print("b[:2, :3]:\n", b[:2, :3])
print("b[1:3, -2:]:\n", b[1:3, -2:])
b[:2]:
 [[1 2 3 4]
 [5 6 7 8]]
b[:2, :3]:
 [[1 2 3]
 [5 6 7]]
b[1:3, -2:]:
 [[ 7  8]
 [11 12]]

12.3.3 条件筛选

a = np.array([
[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
])

print(a[a>7])
[ 8  9 10 11 12]

那么只要我们得到一个 True/False 数据,我都能做筛选

condition = (a > 7) & (a != 10)
print(a[condition])
[ 8  9 11 12]
condition = a > 7
print(np.where(condition, -1, a))
[[ 1  2  3  4]
 [ 5  6  7 -1]
 [-1 -1 -1 -1]]

找到哪里满足条件是Ture的用-1代替,其他还是a里面的数字

condition = a > 7
print(np.where(condition, -1, 2))
[[ 2  2  2  2]
 [ 2  2  2 -1]
 [-1 -1 -1 -1]]

False的用2代替

你可能感兴趣的:(python学习,numpy,python)