第三章:NumPy (2)

木婉清2023/12/01

NumPy(2) 简介

image-2023123002

脑图连接open in new window

数组与元素操作

数值迭代

  • NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
import numpy as np

# 使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代
a = np.arange(6).reshape(2, 3)
print("原始数组是:")
print(a)
print()
print("迭代输出元素:")
for x in np.nditer(a):
    print(x, end=" ")
运行结果

原始数组是: [[0 1 2] [3 4 5]]

迭代输出元素: 0 1 2 3 4 5

import numpy as np

a = np.arange(0, 60, 10)
a = a.reshape(2, 3)
print("原始数组是:")
print(a)
print()
for x in np.nditer(a, op_flags=["readwrite"]):
    x[...] = 3 * x
print("修改后的数组是:")
print(a)

运行结果

原始数组是: [[ 0 10 20] [30 40 50]]

修改后的数组是: [[ 0 30 60] [ 90 120 150]]

  • 如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。
import numpy as np
 # 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 a 的大小)
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print("第一个数组为:")
print(a)
print()
b = np.array([1, 2, 3, 4], dtype=int)
print("第二个数组为:")
print(b)
print()
print("修改后的数组为:")
for x, y in np.nditer([a, b]):
    print("%d:%d" % (x, y), end=", ")
运行结果

第一个数组为: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]]

第二个数组为: [1 2 3 4]

修改后的数组为: 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,

数组变形

  • 修改数组形状
函数描述
reshape不改变数据的条件下修改形状
flat数组元素迭代器
flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel返回展开数组

numpy.reshape

  • 不改变数据的条件下修改形状
numpy.reshape(arr, newshape, order='C')
参数描述
arr要修改形状的数组
newshape整数或者整数数组,新的形状应当兼容原有形状
order'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序
import numpy as np

a = np.arange(8)
print("原始数组:")
print(a)
print("\n")

b = a.reshape(4, 2)
print("修改后的数组:")
print(b)
运行结果

原始数组: [0 1 2 3 4 5 6 7]

修改后的数组: [[0 1] [2 3] [4 5] [6 7]]

numpy.ndarray.flat

  • 数组元素迭代器
import numpy as np

a = np.arange(9).reshape(3, 3)
print("原始数组:")
for row in a:
    print(row)

# 对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
print("迭代后的数组:")
for element in a.flat:
    print(element)
运行结果

始数组: [0 1 2] [3 4 5] [6 7 8] 迭代后的数组: 0 1 2 3 4 5 6 7 8

import numpy as np

a = np.arange(100).reshape(20, 5)
print(a.flat[5])
运行结果

5

numpy.ndarray.flatten

  • 它将多维数组展平为一维数组。

  • 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组

ndarray.flatten(order='C')
参数描述
order'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序
import numpy as np

a = np.arange(8).reshape(2, 4)

print("原数组:")
print(a)
print("\n")
# 默认按行

print("展开的数组:")
print(a.flatten())
print("\n")

print("以 F 风格顺序展开的数组:")
print(a.flatten(order="F"))
运行结果

原数组: [[0 1 2 3] [4 5 6 7]]

展开的数组: [0 1 2 3 4 5 6 7]

以 F 风格顺序展开的数组: [0 4 1 5 2 6 3 7]

numpy.ravel

  • 返回展开数组
numpy.ravel(a, order='C')
参数描述
order'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序
import numpy as np

a = np.arange(8).reshape(2, 4)

print("原数组:")
print(a)
print()

print("调用 ravel 函数之后:")
print(a.ravel())
print()

print("以 F 风格顺序调用 ravel 函数之后:")
print(a.ravel(order="F"))
运行结果

原数组: [[0 1 2 3] [4 5 6 7]]

调用 ravel 函数之后: [0 1 2 3 4 5 6 7]

以 F 风格顺序调用 ravel 函数之后: [0 4 1 5 2 6 3 7]

数组翻转

概览

函数描述
transpose对换数组的维度
ndarray.Tself.transpose() 相同
rollaxis向后滚动指定的轴
swapaxes对换数组的两个轴

transpose

  • 对换数组的维度
numpy.transpose(arr, axes)
参数描述
arr要操作的数组
axes整数列表,对应维度,通常所有维度都会对换
import numpy as np

a = np.arange(12).reshape(3, 4)

print("原数组:")
print(a)
print()

print("对换数组:")
print(np.transpose(a))
运行结果

原数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]

对换数组: [[ 0 4 8] [ 1 5 9] [ 2 6 10] [ 3 7 11]]

import numpy as np

a = np.arange(10).reshape(2, 5)

print("原数组:")
print(a)
print("\n")

print("对换数组:")
print(np.transpose(a))
运行结果

原数组: [[0 1 2 3 4] [5 6 7 8 9]]

对换数组: [[0 5] [1 6] [2 7] [3 8] [4 9]]

ndarray.T

  • self.transpose() 相同
import numpy as np

a = np.arange(20).reshape(4, 5)

print("原数组:")
print(a)
print("\n")

print("转置数组:")
print(a.T)
运行结果

原数组: [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]]

转置数组: [[ 0 5 10 15] [ 1 6 11 16] [ 2 7 12 17] [ 3 8 13 18] [ 4 9 14 19]]

rollaxis

  • 向后滚动指定的轴
numpy.rollaxis(arr, axis, start)
参数描述
arr要操作的数组
axis要向后滚动的轴,其它轴的相对位置不会改变
start默认为零,表示完整的滚动。会滚动到特定位置
import numpy as np

a = np.arange(8).reshape(2, 2, 2)

print("原数组:")
print(a)
print("翻转后:")
# 将轴2放到轴0之前(1, 2, 0)
print(np.rollaxis(a, 2))
print("翻转后:")
# 将轴2放到轴1之前(0, 2, 1)
print(np.rollaxis(a, 2, 1))
运行结果

原数组: [[[0 1] [2 3]]

[[4 5] [6 7]]] 翻转后: [[[0 2] [4 6]]

[[1 3] [5 7]]] 翻转后: [[[0 2] [1 3]]

[[4 6] [5 7]]]

import numpy as np

a = np.arange(9).reshape(3, 3)
print(np.rollaxis(a, 1))
运行结果

[[0 3 6] [1 4 7] [2 5 8]]

swapaxes

  • 对换数组的两个轴
numpy.swapaxes(arr, axis1, axis2)
参数描述
arr要操作的数组
axis1对应第一个轴的整数
axis2对应第二个轴的整数
import numpy as np
a = np.arange(8).reshape(2, 2, 2)
print("原数组:")
print(a)
print("\n")
print("调用 swapaxes 函数后的数组:")
# 交换轴2和轴0
print(np.swapaxes(a, 2, 0))
print("\n")
print("调用 swapaxes 函数后的数组:")
# 交换轴1和轴0
print(np.swapaxes(a, 1, 0))
运行结果

原数组: [[[0 1] [2 3]]

[[4 5] [6 7]]]

调用 swapaxes 函数后的数组: [[[0 4] [2 6]]

[[1 5] [3 7]]]

调用 swapaxes 函数后的数组:

[[[0 1] [4 5]]

[[2 3] [6 7]]]

修改维度

概览

维度描述
broadcast产生模仿广播的对象
broadcast_to将数组广播到新形状
expand_dims扩展数组的形状
squeeze从数组的形状中删除一维条目

numpy.broadcast

  • 产生模仿广播的对象

numpy.broadcast_to

  • 将数组广播到新形状
# 输入数组,新的形状,默认false【为true返回子类,否则返回基类】
numpy.broadcast_to(array, shape, subok)
import numpy as np

a = np.arange(4).reshape(1, 4)

print("原数组:")
print(a)
print("\n")

print("调用 broadcast_to 函数之后:")
print(np.broadcast_to(a, (4, 4)))
运行结果

原数组: [[0 1 2 3]]

调用 broadcast_to 函数之后: [[0 1 2 3] [0 1 2 3] [0 1 2 3] [0 1 2 3]]

numpy.expand_dims

  • 扩展数组的形状
 numpy.expand_dims(arr, axis)
参数描述
arr要操作的数组
axis新轴插入的位置

numpy.squeeze

  • 从数组的形状中删除一维条目
numpy.squeeze(arr, axis)
参数描述
arr要操作的数组
axis整数或整数元组,用于选择形状中一维条目的子集

数组连接

概览

函数描述
concatenate连接沿现有轴的数组序列
stack沿着新的轴加入一系列数组
hstack水平堆叠序列中的数组(列方向)
vstack竖直堆叠序列中的数组(行方向)

numpy.concatenate

  • 连接沿现有轴的数组序列
numpy.concatenate((a1, a2, ...), axis)
参数描述
a1, a2, ...相同类型的数组
axis沿着它连接数组的轴,默认为 0
import numpy as np

a = np.array([[1, 2], [3, 4]])

print("第一个数组:")
print(a)
print("\n")
b = np.array([[5, 6], [7, 8]])

print("第二个数组:")
print(b)
print("\n")
# 两个数组的维度相同

print("沿轴 0 连接两个数组:")
print(np.concatenate((a, b)))
print("\n")

print("沿轴 1 连接两个数组:")
print(np.concatenate((a, b), axis=1))
运行结果

第一个数组: [[1 2] [3 4]]

第二个数组: [[5 6] [7 8]]

沿轴 0 连接两个数组: [[1 2] [3 4] [5 6] [7 8]]

沿轴 1 连接两个数组: [[1 2 5 6] [3 4 7 8]]

numpy.stack

  • 沿着新的轴加入一系列数组
numpy.stack(arrays, axis)
参数描述
arrays相同形状的数组序列
axis返回数组中的轴,输入数组沿着它来堆叠

numpy.hstack

  • 水平堆叠序列中的数组(列方向)

numpy.vstack

  • 竖直堆叠序列中的数组(行方向)

数组分割

概览

函数数组及操作
split将一个数组分割为多个子数组
hsplit将一个数组水平分割为多个子数组(按列)
vsplit将一个数组垂直分割为多个子数组(按行)

numpy.split

  • 将一个数组分割为多个子数组
# 要分割的数组,分割点的位置或分割的块数,沿着哪个轴进行分割【默认为0】
split(ary, indices_or_sections, axis=0)
import numpy as np

a = np.arange(9)

print("第一个数组:")
print(a)
print("\n")

print("将数组分为三个大小相等的子数组:")
b = np.split(a, 3)
print(b)
print("\n")

print("将数组在一维数组中表明的位置分割:")
b = np.split(a, [4, 7])
print(b)
运行结果

第一个数组: [0 1 2 3 4 5 6 7 8]

将数组分为三个大小相等的子数组: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]

将数组在一维数组中表明的位置分割: [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]

numpy.hsplit

  • 将一个数组水平分割为多个子数组(按列)

numpy.vsplit

  • 将一个数组垂直分割为多个子数组(按行)

添加 / 删除元素

概览

函数元素及描述
resize返回指定形状的新数组
append将值添加到数组末尾
insert沿指定轴将值插入到指定下标之前
delete删掉某个轴的子数组,并返回删除后的新数组
unique查找数组内的唯一元素

numpy.resize

  • 返回指定形状的新数组
numpy.resize(arr, shape)
参数描述
arr要修改大小的数组
shape返回数组的新形状
import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])

print("第一个数组:")
print(a)
print("\n")

print("第一个数组的形状:")
print(a.shape)
print("\n")
b = np.resize(a, (3, 2))

print("第二个数组:")
print(b)
print("\n")

print("第二个数组的形状:")
print(b.shape)
print("\n")
# 要注意 a 的第一行在 b 中重复出现,因为尺寸变大了

print("修改第二个数组的大小:")
b = np.resize(a, (3, 3))
print(b)
运行结果

第一个数组: [[1 2 3] [4 5 6]]

第一个数组的形状: (2, 3)

第二个数组: [[1 2] [3 4] [5 6]]

第二个数组的形状: (3, 2)

修改第二个数组的大小: [[1 2 3] [4 5 6] [1 2 3]]

import numpy as np

a = np.array([[1, 2, 3, 4], [4, 5, 6, 7]])
b = np.resize(a, (3, 4))
print(b)
运行结果

[[1 2 3 4] [4 5 6 7] [1 2 3 4]]

numpy.append

  • 将值添加到数组末尾
numpy.append(arr, values, axis=None)
参数描述
arr输入数组
values要向 arr 添加的值,需要和 arr 形状相同(除了要添加的轴)
axis默认为 None 。当 axis 无定义时,是横向加成,返回总是为一维数组!当 axis 有定义的时候,分别为 01 的时候。当 axis 有定义的时候,分别为 01 的时候(列数要相同)。当 axis1时,数组是加在右边(行数要相同)
import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])

print("第一个数组:")
print(a)
print("\n")

print("向数组添加元素:")
print(np.append(a, [7, 8, 9]))
print("\n")

print("沿轴 0 添加元素:")
print(np.append(a, [[7, 8, 9]], axis=0))
print("\n")

print("沿轴 1 添加元素:")
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))
运行结果

第一个数组: [[1 2 3] [4 5 6]]

向数组添加元素: [1 2 3 4 5 6 7 8 9]

沿轴 0 添加元素: [[1 2 3] [4 5 6] [7 8 9]]

沿轴 1 添加元素: [[1 2 3 5 5 5] [4 5 6 7 8 9]]

numpy.insert

  • 沿指定轴将值插入到指定下标之前
numpy.insert(arr, obj, values, axis)
参数描述
arr输入数组
obj在其之前插入值的索引
values要插入的值
axis沿着它插入的轴,如果未提供,则输入数组会被展开
import numpy as np

a = np.array([[1, 2], [3, 4], [5, 6]])

print("第一个数组:")
print(a)
print("\n")

print("未传递 Axis 参数。 在删除之前输入数组会被展开。")
print(np.insert(a, 3, [11, 12]))
print("\n")
print("传递了 Axis 参数。 会广播值数组来配输入数组。")

print("沿轴 0 广播:")
print(np.insert(a, 1, [11], axis=0))
print("\n")

print("沿轴 1 广播:")
print(np.insert(a, 1, 11, axis=1))
运行结果

第一个数组: [[1 2] [3 4] [5 6]]

未传递 Axis 参数。 在删除之前输入数组会被展开。 [ 1 2 3 11 12 4 5 6]

传递了 Axis 参数。 会广播值数组来配输入数组。 沿轴 0 广播: [[ 1 2] [11 11] [ 3 4] [ 5 6]]

沿轴 1 广播: [[ 1 11 2] [ 3 11 4] [ 5 11 6]]

numpy.delete

  • 删掉某个轴的子数组,并返回删除后的新数组
Numpy.delete(arr, obj, axis)
参数描述
arr输入数组
obj可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
axis沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
import numpy as np

a = np.arange(12).reshape(3, 4)

print("第一个数组:")
print(a)
print("\n")

print("未传递 Axis 参数。 在插入之前输入数组会被展开。")
print(np.delete(a, 5))
print("\n")

print("删除第二列:")
print(np.delete(a, 1, axis=1))
print("\n")

print("包含从数组中删除的替代值的切片:")
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(np.delete(a, np.s_[::2]))
运行结果

第一个数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]

未传递 Axis 参数。 在插入之前输入数组会被展开。 [ 0 1 2 3 4 6 7 8 9 10 11]

删除第二列: [[ 0 2 3] [ 4 6 7] [ 8 10 11]]

包含从数组中删除的替代值的切片: [ 2 4 6 8 10]

numpy.unique

  • 查找数组内的唯一元素
numpy.unique(arr, return_index, return_inverse, return_counts)
参数描述
arr输入数组,如果不是一维数组则会展开
return_index如果为 true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
return_inverse如果为 true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
return_counts如果为 true,返回去重数组中的元素在原数组中的出现次数
import numpy as np

a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])

print("第一个数组:")
print(a)
print("\n")

print("第一个数组的去重值:")
u = np.unique(a)
print(u)
print("\n")

print("去重数组的索引数组:")
u, indices = np.unique(a, return_index=True)
print(indices)
print("\n")

print("我们可以看到每个和原数组下标对应的数值:")
print(a)
print("\n")

print("去重数组的下标:")
u, indices = np.unique(a, return_inverse=True)
print(u)
print("\n")

print("下标为:")
print(indices)
print("\n")

print("使用下标重构原数组:")
print(u[indices])
print("\n")

print("返回去重元素的重复数量:")
u, indices = np.unique(a, return_counts=True)
print(u)
print(indices)
运行结果

第一个数组: [5 2 6 2 7 5 6 8 2 9]

第一个数组的去重值: [2 5 6 7 8 9]

去重数组的索引数组: [1 0 2 4 7 9]

我们可以看到每个和原数组下标对应的数值: [5 2 6 2 7 5 6 8 2 9]

去重数组的下标: [2 5 6 7 8 9]

下标为: [1 0 2 0 3 1 2 4 0 5]

使用下标重构原数组: [5 2 6 2 7 5 6 8 2 9]

返回去重元素的重复数量: [2 5 6 7 8 9] [3 2 2 1 1 1]

编辑于 2024/1/4 09:33:12