Python入门教程(二):Numpy数组基础
点击上方蓝字关注我们
本文代码已经整理到百度网盘,领取方式详见文末!
Python中的数组操作几乎等同于Numpy数组操作,今天我们会展示用Numpy数组操作获取数据或者子数组,对数组进行分裂,变形和连接的例子。
首先,我们先介绍几类基本的数组操作:
数组的属性
确定数组的大小,形状,储存大小,数据类型
数组的索引:
获取和设置各个元素的值
数组的切分:
在大的数组中获取或设置更小的子数组
数组的变形
改变给定数组的形状
数组的拼接和分裂
将多个数组合并为一个,以及将一个数组分类为多个。
1
Numpy数组的属性
Numpy数组的属性包括ndim(数组的维度),shape(数组每个维度的大小),size(数组总的大小),dtype(数据类型)以及itemsize(每个数组元素的字节大小)下面我们通过几个示例来了解数组的属性。
首先,生成不同维度的数组。
import numpy as np
np.random.seed(0) # 设置随机种子数,保证程序执行时每次都可以生成同样的随机数组
x1 = np.random.randint(10, size=6) # 一维数组
x2 = np.random.randint(10, size=(3, 4)) # 二维数组,创建三行四列的数组
x3 = np.random.randint(10, size=(3, 4, 5)) # 三维数组
x3
# 查看x3数组
# array([[[8, 1, 5, 9, 8],
# [9, 4, 3, 0, 3],
# [5, 0, 2, 3, 8],
# [1, 3, 3, 3, 7]],
# [[0, 1, 9, 9, 0],
# [4, 7, 3, 2, 7],
# [2, 0, 0, 4, 5],
# [5, 6, 8, 4, 1]],
# [[4, 9, 8, 1, 1],
# [7, 9, 9, 3, 6],
# [7, 2, 0, 3, 5],
# [9, 4, 4, 6, 4]]])
其次,查看x3数组的属性,有结果可见,x3是一个3维的数组,每一个维度都有三行四列,其中一共包含60个元素。
print("x3 ndim: ", x3.ndim)
print("x3 shape:", x3.shape)
print("x3 size: ", x3.size)
# x3 ndim: 3
# x3 shape: (3, 4, 5)
# x3 size: 60
查看数组的数据类型
print("dtype:", x3.dtype)
# dtype: int64
查看数组每个元素的字节大小,一般情况下nbytes=itemsize*size
print("itemsize:", x3.itemsize, "bytes")
print("nbytes:", x3.nbytes, "bytes")
# itemsize: 8 bytes
# nbytes: 480 bytes
2
数组索引-获取单个元素
一维数组
在一维数组中可以通过中括号指定索引获取第i个值。
x1
# array([5, 0, 3, 3, 7, 9])
python中的索引从0开始计数,直到n-1,以下例子获取了x1中的第1一个数值和第5个值。
x1[0]
# 5
x1[4]
# 7
负值索引可以获取末尾索引。
x1[-1]
# 9
x1[-2]
# 7
多维数组
在多维数组中,可以用逗号分隔的索引元组获取元素。
x2
# array([[3, 5, 2, 4],
# [7, 6, 8, 8],
# [1, 6, 7, 7]])
x2[0, 0] # 获取第一个维度中的第一个元素
# 3
x2[2, 0] # 获取第三个维度中的第一个元素
# 1
x2[2, -1] # 获取第三个维度中的倒数第一个元素
# 7
# 修改元素值
x2[0, 0] = 12 # 将第一维的第一个元素值改为12
x2
# array([[12, 5, 2, 4],
# [ 7, 6, 8, 8],
# [ 1, 6, 7, 7]])
3
数组切片-获取子数组
切片(slice)符号为冒号加中括号,可以获取子数组,其语法与python列表的标准切片语法相同,包括三个参数,分别是开始位置,结束位置,bu cha其表现形式如下:
x[start:stop:step]
一维子数组
x = np.arange(10)
x
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 获取前五个元素
x[:5]
# array([0, 1, 2, 3, 4])
# 获取索引5之后的元素
x[5:]
# array([5, 6, 7, 8, 9])
# 获取索引4-7的元素
x[4:7]
# array([4, 5, 6])
# 每隔一个元素
x[::2]
# array([0, 2, 4, 6, 8])
# 每隔一个元素,从索引1开始
x[1::2]
# array([1, 3, 5, 7, 9]
一维逆序数组
# 所有元素逆序排列
x[::-1]
# array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
# 从索引5开始,每隔一个元素逆序
x[5::-2]
# array([5, 3, 1])
多维子数组
多维切片也采用同样的处理方式,用逗号分隔。
x2
# array([[12, 5, 2, 4],
# [ 7, 6, 8, 8],
# [ 1, 6, 7, 7]])
# 截取两行三列
x2[:2, :3]
# array([[12, 5, 2],
# [ 7, 6, 8]])
# 所有行每隔一列
x2[:3, ::2]
# array([[12, 2],
# [ 7, 8],
# [ 1, 7]])
#子数组维度逆序
x2[::-1, ::-1]
# array([[ 7, 7, 6, 1],
# [ 8, 8, 6, 7],
# [ 4, 2, 5, 12]])
获取数组的行和列
如果需要获取数组的单行或者单列,可以通过索引与切片组合起来实现这个功能,用冒号(:)来表示这个功能。
# 获取x2的第一列
print(x2[:, 0])
# [12 7 1]
# 获取x2的第一行
print(x2[0, :])
# [12 5 2 4]
print(x2[0])
# [12 5 2 4]
在获取行数时,出于语法的简洁考虑,可以省略空的切片。如上例所示,x2[0, :]=x2[0]
4
数组的变形
reshape()函数实现数组的变形
reshape()函数实现数组的变形需要保证的是,与啊是数组的大小必须和变形后的数组大小保持一致。
#将1-9放入到3*3的矩阵中
grid = np.arange(1, 10).reshape((3, 3))
print(grid)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
reshape()或newaxis()将一维数组转换为二维数组的行或列的矩阵
x = np.array([1, 2, 3])
# 通过变形获得的行向量
x.reshape((1, 3))
# array([[1, 2, 3]])
# 通过newaxis获得的行向量
x[np.newaxis, :]
# array([[1, 2, 3]])
# 通过变形获得的列向量
x.reshape((3, 1))
# array([[1],
# [2],
# [3]])
# 通过newaxis获得的列项量
x[:, np.newaxis]
# array([[1],
# [2],
# [3]])
5
数组的拼接和分裂
数据的拼接
当我们遇到多个数组,想要把这些数组合并到一起就涉及到了数组的拼接,常用的拼接函数有np.concatenate, np.vstack, 和np.hstack,具体用法请看下面示例。
# np.concatenate将元素或列表作为第一参数
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])
# array([1, 2, 3, 3, 2, 1])
# np.concatenate也可以拼接多个数组
z = [99, 99, 99]
print(np.concatenate([x, y, z]))
# [ 1 2 3 3 2 1 99 99 99]
# 拼接多维数组
grid = np.array([[1, 2, 3],
[4, 5, 6]])
# 沿着第一个轴拼接
np.concatenate([grid, grid])
# array([[1, 2, 3],
# [4, 5, 6],
# [1, 2, 3],
# [4, 5, 6]])
# 沿着第二个轴拼接,从0开始索引
np.concatenate([grid, grid], axis=1)
# array([[1, 2, 3, 1, 2, 3],
# [4, 5, 6, 4, 5, 6]])
np.vstack(垂直栈)和np.hstack(水平栈)实现沿着固定维度处理数组。
x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7],
[6, 5, 4]])
# 垂直栈数组
np.vstack([x, grid])
# array([[1, 2, 3],
# [9, 8, 7],
# [6, 5, 4]])
# 水平栈数组
y = np.array([[99],
[99]])
np.hstack([grid, y])
# array([[ 9, 8, 7, 99],
# [ 6, 5, 4, 99]])
与拼接相反的过程是分裂,分裂常用到的函数有np.split, np.hsplit, and np.vsplit函数实现,可以向上传递一个索引列表作为参数,索引列表记录为分裂点位置。N个分裂点会得到N+1个子数组
x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)
# [1 2 3] [99 99] [3 2 1]
grid = np.arange(16).reshape((4, 4))
grid
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)
# [[0 1 2 3]
# [4 5 6 7]]
# [[ 8 9 10 11]
# [12 13 14 15]]
left, right = np.hsplit(grid, [2])
print(left)
print(right)
# [[ 0 1]
# [ 4 5]
# [ 8 9]
# [12 13]]
# [[ 2 3]
# [ 6 7]
# [10 11]
# [14 15]]
在公众号后台回复【Nnupy基础】,即可获得本文全部代码!
python系列文章持续更新中,欢迎加入数据人专属交流群
往期推荐
你的Python 基础知识是成体系的吗?这套核心知识体系思维导图送给你!
分享数据知识,成就数据理想
点个在看 你最好看