1、shape的用法
arr.shape[1]
是用来获取 NumPy 数组 arr
的形状(即维度大小)中的第二个元素的值。shape
是 NumPy 数组的一个属性,它返回一个元组,表示数组的各个维度的大小。
解释
arr.shape
返回一个元组,其中包含了数组各个维度的大小。arr.shape[0]
表示第一个维度(通常是行数)的大小。arr.shape[1]
表示第二个维度(通常是列数)的大小。- 以此类推,
arr.shape[n]
表示第n+1
个维度的大小。
示例
假设我们有一个二维数组 arr
,形状为 (3, 4)
,即 3 行 4 列。
import numpy as np
# 创建一个 3x4 的二维数组
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# 获取数组的形状
shape = arr.shape
print("Shape of the array:", shape)
# 输出:
# Shape of the array: (3, 4)
# 获取行数
num_rows = arr.shape[0]
# 获取列数
num_cols = arr.shape[1]
print("Number of rows:", num_rows)
print("Number of columns:", num_cols)
# 输出:
# Number of rows: 3
# Number of columns: 4
在这个例子中:
arr.shape
返回(3, 4)
,表示数组有 3 行 4 列。arr.shape[0]
返回 3,表示行数。arr.shape[1]
返回 4,表示列数。
更多维度的例子
假设我们有一个三维数组 arr
,形状为 (2, 3, 4)
。
import numpy as np
# 创建一个 2x3x4 的三维数组
arr = np.array([[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]],
[[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]]])
# 获取数组的形状
shape = arr.shape
print("Shape of the array:", shape)
# 输出:
# Shape of the array: (2, 3, 4)
# 获取第一个维度的大小
dim1 = arr.shape[0]
# 获取第二个维度的大小
dim2 = arr.shape[1]
# 获取第三个维度的大小
dim3 = arr.shape[2]
print("Size of the first dimension:", dim1)
print("Size of the second dimension:", dim2)
print("Size of the third dimension:", dim3)
# 输出:
# Size of the first dimension: 2
# Size of the second dimension: 3
# Size of the third dimension: 4
在这个例子中:
arr.shape
返回(2, 3, 4)
,表示数组有 2 个 “页”,每个页有 3 行 4 列。arr.shape[0]
返回 2,表示 “页” 的数量。arr.shape[1]
返回 3,表示行数。arr.shape[2]
返回 4,表示列数。
总结
arr.shape
返回一个元组,表示数组的各维度大小。arr.shape[0]
表示第一个维度(通常是行数)的大小。arr.shape[1]
表示第二个维度(通常是列数)的大小。- 以此类推,
arr.shape[n]
表示第n+1
个维度的大小。
2、reshape如何使用
np.reshape
是 NumPy 库中用于改变数组形状的方法,但不改变数组中的数据。这个方法非常有用,当你需要将数组转换成不同的维度时可以使用它。下面是 np.reshape
的基本用法以及一些示例:
基本语法
numpy.reshape(a, newshape, order='C')
a
:要重塑的原始数组。newshape
:整数或整数元组,表示新的形状。如果提供的是一个整数,则结果必须是1维数组;如果是整数元组,则指定每个维度的大小。可以使用-1
来自动推断某个维度的大小。order
:可选参数,指定数组元素的读取顺序。‘C’ 表示 C 风格(行优先),‘F’ 表示 Fortran 风格(列优先),‘A’ 根据数组存储方式选择。
示例
-
导入 NumPy
import numpy as np
-
创建一个一维数组并重塑为二维数组
arr = np.arange(6) # 创建一个从0到5的一维数组 reshaped_arr = np.reshape(arr, (2, 3)) # 将其重塑为2行3列的二维数组 print(reshaped_arr) # 输出: # [[0 1 2] # [3 4 5]]
-
使用 -1 自动计算维度大小
如果你知道其他维度的大小,但不确定某一个维度的具体值,可以使用-1
让 NumPy 自动计算:reshaped_arr = np.reshape(arr, (2, -1)) # NumPy 会自动计算第二个维度应为3 print(reshaped_arr) # 输出与上相同
-
保持总元素数量不变
新的形状必须能够容纳原数组的所有元素。例如,不能将含有6个元素的数组重塑为2x4的形状,因为这需要8个元素:# 这会产生错误 # np.reshape(arr, (2, 4))
-
多维数组的重塑
也可以对多维数组进行重塑:arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) reshaped_arr_2d = np.reshape(arr_2d, (3, 2)) # 重塑为3行2列 print(reshaped_arr_2d) # 输出: # [[1 2] # [3 4] # [5 6]]
-
指定读取顺序
默认情况下,reshape
按照 ‘C’ 顺序处理数据。如果你希望按照 ‘F’ 顺序来处理,可以指定order='F'
:reshaped_arr_f_order = np.reshape(arr, (2, 3), order='F') print(reshaped_arr_f_order) # 输出: # [[0 2 4] # [1 3 5]]
通过这些例子,你可以看到如何利用 np.reshape
方法来灵活地调整数组的结构以满足特定的需求。记住,在重塑过程中,数组的数据总量不会改变,只有它们的排列方式被重新组织。
3、sort如何使用
下面我会为每个函数提供更详细的说明和具体的例子。
np.argsort
np.argsort
返回数组元素从小到大的索引值。这在你需要知道排序后元素的原始位置时非常有用。
示例:
import numpy as np
# 创建一个一维数组
arr = np.array([10, 60, 20, 40, 30])
# 获取排序后的索引
sorted_indices = np.argsort(arr)
print("Original array:", arr)
print("Sorted indices:", sorted_indices)
# 输出: Original array: [10 60 20 40 30]
# Sorted indices: [0 2 4 3 1]
# 使用索引来获取排序后的数组
sorted_arr = arr[sorted_indices]
print("Sorted array using indices:", sorted_arr)
# 输出: Sorted array using indices: [10 20 30 40 60]
上面的arr[sorted_indices],这是花式索引:
arr[sorted_indices]
这种写法是利用了 NumPy 数组的索引功能。在 NumPy 中,你可以使用一个数组作为索引来访问另一个数组中的元素。这种技术称为花式索引(fancy indexing)。通过这种方式,可以非常方便地根据某个顺序来重新排列数组。
为什么可以写成 arr[sorted_indices]
的形式
当你调用 np.argsort(arr)
时,它返回的是一个包含原数组 arr
元素从小到大排序后对应索引的数组。例如:
import numpy as np
arr = np.array([10, 60, 20, 40, 30])
sorted_indices = np.argsort(arr)
print("Original array:", arr)
print("Sorted indices:", sorted_indices)
# 输出:
# Original array: [10 60 20 40 30]
# Sorted indices: [0 2 4 3 1]
这里的 sorted_indices
数组 [0, 2, 4, 3, 1]
表示原数组 arr
中的元素按升序排列后的索引位置。具体来说:
- 索引 0 对应值 10(最小)
- 索引 2 对应值 20
- 索引 4 对应值 30
- 索引 3 对应值 40
- 索引 1 对应值 60(最大)
当你使用 arr[sorted_indices]
时,NumPy 会根据 sorted_indices
中的每个索引值从 arr
中提取对应的元素,并将这些元素按 sorted_indices
的顺序组合成一个新的数组。这样就得到了一个按升序排列的新数组。
示例代码
import numpy as np
# 原始数组
arr = np.array([10, 60, 20, 40, 30])
# 获取排序后的索引
sorted_indices = np.argsort(arr)
# 使用排序后的索引获取排序后的数组
sorted_arr = arr[sorted_indices]
print("Original array:", arr)
print("Sorted indices:", sorted_indices)
print("Sorted array using indices:", sorted_arr)
# 输出:
# Original array: [10 60 20 40 30]
# Sorted indices: [0 2 4 3 1]
# Sorted array using indices: [10 20 30 40 60]
在这个例子中,arr[sorted_indices]
相当于执行了以下操作:
arr[0]
-> 10arr[2]
-> 20arr[4]
-> 30arr[3]
-> 40arr[1]
-> 60
然后将这些值按 sorted_indices
的顺序组合起来,得到最终的排序数组 [10, 20, 30, 40, 60]
。
这种花式索引的方法不仅简洁,而且效率高,因为它是基于底层 C 语言实现的,可以直接操作内存中的数据。
花式索引(fancy indexing)是 NumPy 中一种强大的数组索引方式,它允许你使用整数数组作为索引来选择数组中的元素。这种方式非常灵活,可以用来实现复杂的数组操作。下面是关于如何使用花式索引、何时可以使用以及何时不适用的一些详细说明。
如何使用花式索引
基本用法:
- 你可以使用一个整数数组来索引另一个数组,这个整数数组中的每个元素都代表你要从目标数组中选取的元素的位置。
- 花式索引的结果是一个新的数组,包含按照索引顺序排列的元素。
示例:
import numpy as np
# 创建一个一维数组
arr = np.array([10, 20, 30, 40, 50])
# 使用花式索引
indices = [1, 3, 0] # 选择索引为1, 3, 0的元素
selected_elements = arr[indices]
print(selected_elements) # 输出: [20 40 10]
# 多维数组的花式索引
matrix = np.array([[1, 2], [3, 4], [5, 6]])
row_indices = [0, 2] # 选择第0行和第2行
col_indices = [1, 0] # 选择第1列和第0列
selected_elements = matrix[row_indices, col_indices]
print(selected_elements) # 输出: [2 5]
何时可以使用花式索引
- 需要根据特定索引选择元素时:当你有一组特定的索引,想要从中提取或重新排列数据时。
- 需要对数组进行部分排序或重组时:如
argsort
的结果可以直接用于花式索引以获取排序后的数组。 - 需要访问多维数组中的非连续元素时:例如,从二维数组中提取特定位置的元素。
- 需要进行条件选择时:结合布尔索引,可以从数组中选择满足某些条件的元素。
何时不可以使用花式索引
- 索引数组不是整数类型时:花式索引要求索引数组必须是整数类型。如果你尝试使用浮点数或其他类型的索引,会引发错误。
- 索引超出范围时:如果提供的索引超出了数组的实际范围,NumPy 会抛出
IndexError
。 - 性能考虑:虽然花式索引很强大,但在处理非常大的数组时,它可能不如切片那么高效。对于简单的连续子集,通常推荐使用切片。
示例 - 错误情况:
# 索引数组不是整数类型
arr = np.array([10, 20, 30, 40, 50])
indices = [1.5, 3, 0] # 浮点数索引
try:
selected_elements = arr[indices]
except IndexError as e:
print(e) # 输出: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
# 索引超出范围
arr = np.array([10, 20, 30, 40, 50])
indices = [1, 6, 0] # 索引6超出了范围
try:
selected_elements = arr[indices]
except IndexError as e:
print(e) # 输出: index 6 is out of bounds for axis 0 with size 5
通过这些示例和解释,你应该能够更好地理解花式索引的工作原理以及在什么情况下应该使用它。记住,合理地使用花式索引可以使你的代码更加简洁和高效。
np.lexsort
np.lexsort
是 NumPy 中用于执行间接排序的函数,特别适用于多键排序。它返回一个索引数组,该索引数组可以用来对原始数据进行排序。lexsort
的名称来源于“字典序排序”(lexicographical sort),即先按第一个关键字排序,如果第一个关键字相同,则按第二个关键字排序,以此类推。
基本语法
numpy.lexsort(keys, axis=-1)
keys
:一个元组或列表,包含多个一维数组,这些数组是排序的关键字。axis
:指定沿哪个轴进行排序,默认为最后一个轴。
如何使用 np.lexsort
示例 1: 对二维数据进行排序
假设我们有一个学生的成绩表,其中第一列是数学成绩,第二列是英语成绩,我们想先按数学成绩排序,如果数学成绩相同,则按英语成绩排序。
import numpy as np
# 学生成绩表
math_scores = np.array([80, 70, 80, 90, 70])
english_scores = np.array([75, 85, 90, 85, 70])
# 使用 lexsort 进行排序
# 注意:keys 参数中的顺序是从低优先级到高优先级
sorted_indices = np.lexsort((english_scores, math_scores))
# 输出排序后的索引
print("Sorted indices:", sorted_indices)
# 输出: Sorted indices: [4 1 0 2 3]
# 使用排序后的索引来获取排序后的成绩
sorted_math = math_scores[sorted_indices]
sorted_english = english_scores[sorted_indices]
print("Sorted Math Scores:", sorted_math)
# 输出: Sorted Math Scores: [70 70 80 80 90]
print("Sorted English Scores:", sorted_english)
# 输出: Sorted English Scores: [70 85 75 90 85]
在这个例子中,np.lexsort
首先根据 math_scores
排序,然后在 math_scores
相同的情况下再根据 english_scores
排序。
示例 2: 对结构化数组进行排序
如果你有一个结构化数组,并且想要根据多个字段进行排序,也可以使用 np.lexsort
。
import numpy as np
# 创建一个结构化数组
data = np.array([
(80, 75, 'Alice'),
(70, 85, 'Bob'),
(80, 90, 'Charlie'),
(90, 85, 'David'),
(70, 70, 'Eve')
], dtype=[('math', int), ('english', int), ('name', 'U10')])
# 提取需要排序的字段
math_scores = data['math']
english_scores = data['english']
# 使用 lexsort 进行排序
sorted_indices = np.lexsort((english_scores, math_scores))
# 使用排序后的索引来获取排序后的数据
sorted_data = data[sorted_indices]
print("Sorted Data:")
print(sorted_data)
# 输出:
# Sorted Data:
# [(70, 70, 'Eve') (70, 85, 'Bob') (80, 75, 'Alice') (80, 90, 'Charlie')
# (90, 85, 'David')]
在这个例子中,np.lexsort
先按 math
字段排序,然后在 math
字段相同的情况下再按 english
字段排序。
总结
np.lexsort
适用于需要根据多个关键字进行排序的情况。通过返回排序后的索引,你可以轻松地对原始数据进行重新排列。记住,keys
参数中的顺序是从低优先级到高优先级,这意味着最后提供的关键字具有最高的优先级。
np.searchsorted
np.searchsorted
是 NumPy 中的一个函数,用于在已排序的数组中查找插入位置,以保持数组的有序状态。这个函数非常有用,尤其是在你需要找到某个值应该插入到已排序数组中的哪个位置时。
基本语法
numpy.searchsorted(a, v, side='left', sorter=None)
a
:一维的、已经排序好的数组。v
:要查找插入位置的值或值的数组。side
:指定插入的位置是左侧还是右侧。如果为'left'
(默认),则返回的是使得a[i-1] < v <= a[i]
的最小的i
;如果为'right'
,则返回的是使得a[i-1] <= v < a[i]
的最小的i
。sorter
:一个整数数组,表示a
的排序索引。如果a
本身不是排序好的,可以提供这个参数来避免额外的排序操作。
使用示例
示例 1: 查找单个值的插入位置
假设我们有一个已排序的数组,并且想要知道一个值应该插入到数组中的哪个位置。
import numpy as np
# 已排序的一维数组
a = np.array([1, 2, 4, 5])
# 要查找插入位置的值
v = 3
# 查找左侧插入位置
left_position = np.searchsorted(a, v, side='left')
print("Left position for insertion:", left_position)
# 输出: Left position for insertion: 2
# 查找右侧插入位置
right_position = np.searchsorted(a, v, side='right')
print("Right position for insertion:", right_position)
# 输出: Right position for insertion: 2
在这个例子中,3
应该插入到索引 2
的位置,因为 2 < 3 <= 4
。
示例 2: 查找多个值的插入位置
如果你有多个值需要查找插入位置,v
可以是一个数组。
import numpy as np
# 已排序的一维数组
a = np.array([1, 2, 4, 5])
# 要查找插入位置的多个值
v = np.array([0, 3, 6])
# 查找左侧插入位置
left_positions = np.searchsorted(a, v, side='left')
print("Left positions for insertion:", left_positions)
# 输出: Left positions for insertion: [0 2 4]
# 查找右侧插入位置
right_positions = np.searchsorted(a, v, side='right')
print("Right positions for insertion:", right_positions)
# 输出: Right positions for insertion: [0 2 4]
在这个例子中,0
应该插入到索引 0
的位置,3
应该插入到索引 2
的位置,6
应该插入到索引 4
的位置(即数组的末尾)。
示例 3: 使用 sorter
参数
如果你的数组没有预先排序,但你知道它的排序顺序,你可以使用 sorter
参数来避免额外的排序操作。
import numpy as np
# 未排序的一维数组
a = np.array([4, 2, 1, 5])
# 数组的排序索引
sorter = np.argsort(a) # [2, 1, 0, 3]
# 要查找插入位置的值
v = 3
# 使用 sorter 参数查找插入位置
position = np.searchsorted(a, v, sorter=sorter)
print("Position for insertion:", position)
# 输出: Position for insertion: 2
在这个例子中,虽然 a
本身没有排序,但我们通过 sorter
参数告诉 searchsorted
函数 a
的正确排序顺序,从而正确地找到了插入位置。
总结
np.searchsorted
是一个非常有用的函数,特别是在处理已排序数据时。它可以帮助你快速找到值应该插入的位置,而不需要对整个数组进行重新排序。记住,side
参数决定了插入的具体位置,而 sorter
参数可以在不预先排序的情况下使用。
np.partition
np.partition
是 NumPy 中的一个函数,用于对数组进行部分排序。与完全排序不同,partition
会将数组中的元素分为两部分:一部分是小于等于某个值(称为“枢轴”或“pivot”)的元素,另一部分是大于该值的元素。这个函数在你只需要找到数组中第 k 小(或大)的元素时非常有用,而不需要对整个数组进行完整的排序。
基本语法
numpy.partition(a, kth, axis=-1, kind='introselect', order=None)
a
:要进行分区的输入数组。kth
:一个整数或整数列表,表示分区的位置。如果是一个整数,那么第 k 个元素会被放在它最终排序后的位置,并且所有小于它的元素都在它的左边,所有大于它的元素都在右边。如果是一个整数列表,则会对多个位置进行分区。axis
:指定沿哪个轴进行分区,默认为最后一个轴。kind
:指定使用的算法,默认为'introselect'
。order
:对于结构化数组,可以指定字段来控制排序顺序。
使用示例
示例 1: 对一维数组进行分区
假设我们有一个一维数组,并且我们想要找到第 3 小的元素,并将其放置在正确的位置上。
import numpy as np
# 创建一个一维数组
arr = np.array([7, 2, 3, 1, 6, 5, 4])
# 找到第 3 小的元素并进行分区
partitioned_arr = np.partition(arr, 2)
print("Partitioned array:", partitioned_arr)
# 输出: Partitioned array: [1 2 3 7 6 5 4]
# 第 3 小的元素 3 被放在了索引 2 的位置,左侧都是比它小的元素,右侧都是比它大的元素
在这个例子中,np.partition(arr, 2)
将数组 arr
分区,使得第 3 小的元素(即 3
)被放在索引 2
的位置,所有小于 3
的元素都在它的左边,所有大于 3
的元素都在它的右边。
示例 2: 对多维数组进行分区
假设我们有一个二维数组,并且我们想要沿着某一轴进行分区。
import numpy as np
# 创建一个二维数组
arr_2d = np.array([[7, 2, 3], [1, 6, 5], [4, 3, 8]])
# 沿着行方向(axis=1)进行分区,找到每行的第 2 小的元素
partitioned_arr_2d = np.partition(arr_2d, 1, axis=1)
print("Partitioned 2D array:")
print(partitioned_arr_2d)
# 输出:
# Partitioned 2D array:
# [[2 3 7]
# [1 5 6]
# [3 4 8]]
# 每一行的第 2 小的元素都被放在了索引 1 的位置
在这个例子中,np.partition(arr_2d, 1, axis=1)
沿着行方向对每一行进行分区,使得每行的第 2 小的元素被放在索引 1
的位置。
示例 3: 对多个位置进行分区
如果你需要对多个位置进行分区,可以传递一个整数列表给 kth
参数。
import numpy as np
# 创建一个一维数组
arr = np.array([7, 2, 3, 1, 6, 5, 4])
# 对第 2 和第 4 小的元素进行分区
partitioned_arr = np.partition(arr, [1, 3])
print("Partitioned array with multiple kth values:", partitioned_arr)
# 输出: Partitioned array with multiple kth values: [1 2 3 4 7 6 5]
# 第 2 小的元素 2 被放在索引 1 的位置,第 4 小的元素 4 被放在索引 3 的位置
在这个例子中,np.partition(arr, [1, 3])
对第 2 小和第 4 小的元素进行了分区,使得它们分别被放在索引 1
和 3
的位置。
总结
np.partition
是一个高效的工具,适用于当你只需要找到数组中某些特定位置的元素时,而不需要对整个数组进行完全排序。通过指定 kth
参数,你可以灵活地控制分区的位置。这对于快速查找中位数、百分位数等统计量非常有用。
4、axis参数的具体含义
在 NumPy 中,axis
参数用于指定对多维数组进行操作的轴(维度)。理解 axis
的含义对于正确使用许多 NumPy 函数非常重要。下面我将详细解释 axis
参数的含义,并通过一些示例来说明它的用法。
axis
参数的基本含义
axis=0
:沿着垂直方向(行方向)进行操作,通常称为“列”操作。axis=1
:沿着水平方向(列方向)进行操作,通常称为“行”操作。- 对于更高维度的数组,
axis
依次表示更高的维度。例如,在三维数组中,axis=2
表示第三个维度的操作。
示例说明
一维数组
对于一维数组,axis
参数通常是不需要的,因为只有一个维度。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print("Sum of the array:", np.sum(arr)) # 输出: Sum of the array: 15
二维数组
对于二维数组,axis
参数可以是 0 或 1。
import numpy as np
# 创建一个二维数组
arr_2d = np.array([[1, 2, 3],
[4, 5, 6]])
# 沿着 axis=0 (列) 进行求和
sum_axis_0 = np.sum(arr_2d, axis=0)
print("Sum along axis=0 (columns):", sum_axis_0)
# 输出: Sum along axis=0 (columns): [5 7 9]
# 沿着 axis=1 (行) 进行求和
sum_axis_1 = np.sum(arr_2d, axis=1)
print("Sum along axis=1 (rows):", sum_axis_1)
# 输出: Sum along axis=1 (rows): [6 15]
在这个例子中:
np.sum(arr_2d, axis=0)
对每一列进行求和,结果是一个一维数组[5, 7, 9]
。np.sum(arr_2d, axis=1)
对每一行进行求和,结果是一个一维数组[6, 15]
。
三维数组
对于三维数组,axis
参数可以是 0、1 或 2。
import numpy as np
# 创建一个三维数组
arr_3d = np.array([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]])
# 沿着 axis=0 (深度) 进行求和
sum_axis_0 = np.sum(arr_3d, axis=0)
print("Sum along axis=0 (depth):")
print(sum_axis_0)
# 输出:
# Sum along axis=0 (depth):
# [[ 6 8]
# [10 12]]
# 沿着 axis=1 (行) 进行求和
sum_axis_1 = np.sum(arr_3d, axis=1)
print("Sum along axis=1 (rows):")
print(sum_axis_1)
# 输出:
# Sum along axis=1 (rows):
# [[ 4 6]
# [12 14]]
# 沿着 axis=2 (列) 进行求和
sum_axis_2 = np.sum(arr_3d, axis=2)
print("Sum along axis=2 (columns):")
print(sum_axis_2)
# 输出:
# Sum along axis=2 (columns):
# [[ 3 7]
# [11 15]]
在这个例子中:
np.sum(arr_3d, axis=0)
对每个深度层进行求和,结果是一个二维数组。np.sum(arr_3d, axis=1)
对每个二维层的行进行求和,结果是一个二维数组。np.sum(arr_3d, axis=2)
对每个二维层的列进行求和,结果是一个二维数组。
其他常见函数中的 axis
参数
除了 np.sum
,很多其他 NumPy 函数也支持 axis
参数,如 np.mean
、np.max
、np.min
、np.argmax
、np.argmin
等。这些函数中的 axis
参数都具有相同的含义。
总结
axis=0
通常表示沿着垂直方向(列)进行操作。axis=1
通常表示沿着水平方向(行)进行操作。- 对于更高维度的数组,
axis
依次表示更高的维度。
通过理解 axis
参数的含义,你可以更灵活地对多维数组进行各种操作。
5、给数组增加维度(轴)
np.newaxis
和 np.expand_dims
都是 NumPy 中用于增加数组维度的工具。它们在处理多维数据时非常有用,尤其是在需要将一维数组转换为二维数组,或者在特定位置插入新轴时。
np.newaxis
np.newaxis
是一个特殊的索引对象,它可以在现有数组中插入一个新的轴。这通常用于将一维数组转换为列向量或行向量,或者在需要广播操作时添加新的维度。
基本用法
arr[:, np.newaxis]
:在第二个维度(列方向)上插入一个新的轴。arr[np.newaxis, :]
:在第一个维度(行方向)上插入一个新的轴。
示例
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3])
# 将一维数组转换为列向量
column_vector = arr[:, np.newaxis]
print("Column vector:")
print(column_vector)
# 输出:
# Column vector:
# [[1]
# [2]
# [3]]
# 将一维数组转换为行向量
row_vector = arr[np.newaxis, :]
print("Row vector:")
print(row_vector)
# 输出:
# Row vector:
# [[1 2 3]]
np.expand_dims
np.expand_dims
函数允许你在指定的位置插入一个新的轴。这个函数更加灵活,可以明确指定在哪个位置插入新的轴。
基本语法
numpy.expand_dims(a, axis)
a
:输入数组。axis
:要插入新轴的位置。可以是一个整数或整数列表。
示例
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3])
# 在第一个维度(行方向)上插入一个新的轴
expanded_row = np.expand_dims(arr, axis=0)
print("Expanded to row vector:")
print(expanded_row)
# 输出:
# Expanded to row vector:
# [[1 2 3]]
# 在第二个维度(列方向)上插入一个新的轴
expanded_column = np.expand_dims(arr, axis=1)
print("Expanded to column vector:")
print(expanded_column)
# 输出:
# Expanded to column vector:
# [[1]
# [2]
# [3]]
# 对于多维数组
arr_2d = np.array([[1, 2], [3, 4]])
# 在第三个维度上插入一个新的轴
expanded_3d = np.expand_dims(arr_2d, axis=2)
print("Expanded to 3D array:")
print(expanded_3d)
# 输出:
# Expanded to 3D array:
# [[[1]
# [2]]
#
# [[3]
# [4]]]
# 在多个位置插入新的轴
expanded_multi_axis = np.expand_dims(arr, axis=(0, 1))
print("Expanded with multiple axes:")
print(expanded_multi_axis)
# 输出:
# Expanded with multiple axes:
# [[[1 2 3]]]
总结
np.newaxis
:通过在索引中使用np.newaxis
,你可以在特定位置插入新的轴。这种方法简洁且直观,但仅限于在单个位置插入新的轴。np.expand_dims
:通过np.expand_dims
函数,你可以更灵活地在任何位置插入新的轴,并且可以同时在多个位置插入新的轴。这种方法更加通用,适用于复杂的多维数组操作。
这两种方法都可以用来增加数组的维度,选择哪种方法取决于你的具体需求和代码风格。如果你只需要在单个位置插入新的轴,np.newaxis
可能更简洁;如果你需要在多个位置插入新的轴,或者希望代码更具可读性,np.expand_dims
是更好的选择。
在多个位置插入新轴的示例可能看起来有些复杂,但通过详细的解释和更多的例子,我们可以更好地理解这个过程。让我们再来看一下
np.expand_dims
在多个位置插入新轴的例子,并逐步解析。
示例解析
假设我们有一个一维数组 arr
,我们想在多个位置插入新的轴。具体来说,我们希望在第一个维度(行方向)和第二个维度(列方向)都插入新的轴。
import numpy as np
# 创建一个一维数组
arr = np.array([1, 2, 3])
# 在多个位置插入新的轴
expanded_multi_axis = np.expand_dims(arr, axis=(0, 1))
print("Expanded with multiple axes:")
print(expanded_multi_axis)
# 输出:
# Expanded with multiple axes:
# [[[1 2 3]]]
逐步解析
-
原始数组:
arr = np.array([1, 2, 3])
- 形状:
(3,)
- 维度:1
- 形状:
-
插入新轴:
- 我们使用
axis=(0, 1)
来指定在第 0 个维度和第 1 个维度上插入新的轴。 - 插入新轴后的形状会变成
(1, 1, 3)
,即增加两个新的维度。
- 我们使用
-
结果数组:
- 结果是一个三维数组,形状为
(1, 1, 3)
。 - 数组的内容仍然是
[1, 2, 3]
,但现在它被包裹在一个新的维度中。
- 结果是一个三维数组,形状为
详细解释
-
原始数组:
[1, 2, 3]
-
在第 0 个维度插入新轴:
- 这会在最外层添加一个新的维度,将数组变成一个二维数组。
- 结果是:
[[1, 2, 3]]
- 形状变为
(1, 3)
。
-
在第 1 个维度插入新轴:
- 这会在当前的第 1 个维度(即原来的第 0 个维度)插入一个新的维度。
- 结果是:
[[[1, 2, 3]]]
- 形状变为
(1, 1, 3)
。
更多示例
示例 1: 在第 0 个维度和第 2 个维度插入新轴
假设我们有一个二维数组 arr_2d
,我们想在第 0 个维度和第 2 个维度插入新的轴。
import numpy as np
# 创建一个二维数组
arr_2d = np.array([[1, 2], [3, 4]])
# 在第 0 个维度和第 2 个维度插入新轴
expanded_multi_axis = np.expand_dims(arr_2d, axis=(0, 2))
print("Expanded with multiple axes:")
print(expanded_multi_axis)
# 输出:
# Expanded with multiple axes:
# [[[[1]
# [2]]
#
# [[3]
# [4]]]]
-
原始数组:
[[1, 2], [3, 4]]
- 形状:
(2, 2)
- 维度:2
- 形状:
-
插入新轴:
axis=(0, 2)
表示在第 0 个维度和第 2 个维度插入新的轴。- 插入新轴后的形状会变成
(1, 2, 2, 1)
。
-
结果数组:
- 结果是一个四维数组,形状为
(1, 2, 2, 1)
。 - 数组的内容仍然是
[[1, 2], [3, 4]]
,但现在它被包裹在两个新的维度中。
- 结果是一个四维数组,形状为
示例 2: 在第 1 个维度和第 2 个维度插入新轴
假设我们有一个二维数组 arr_2d
,我们想在第 1 个维度和第 2 个维度插入新的轴。
import numpy as np
# 创建一个二维数组
arr_2d = np.array([[1, 2], [3, 4]])
# 在第 1 个维度和第 2 个维度插入新轴
expanded_multi_axis = np.expand_dims(arr_2d, axis=(1, 2))
print("Expanded with multiple axes:")
print(expanded_multi_axis)
# 输出:
# Expanded with multiple axes:
# [[[1 2]]
#
# [[3 4]]]
-
原始数组:
[[1, 2], [3, 4]]
- 形状:
(2, 2)
- 维度:2
- 形状:
-
插入新轴:
axis=(1, 2)
表示在第 1 个维度和第 2 个维度插入新的轴。- 插入新轴后的形状会变成
(2, 1, 1, 2)
。
-
结果数组:
- 结果是一个四维数组,形状为
(2, 1, 1, 2)
。 - 数组的内容仍然是
[[1, 2], [3, 4]]
,但现在它被包裹在两个新的维度中。
- 结果是一个四维数组,形状为
总结
np.expand_dims
可以在指定的位置插入新的轴。- 使用
axis
参数可以指定要插入新轴的位置。 - 多个位置插入新轴时,
axis
参数可以是一个整数列表,表示在这些位置插入新的轴。 - 通过这种方式,你可以灵活地增加数组的维度,以便进行更复杂的操作或满足特定的需求。