NumPy介绍

Numpy介绍

NumPy(Numerical Python的简称)是Python编程语言的一个库,主要用于科学计算和数据处理。它提供了支持高性能多维数组和矩阵运算的功能,以及大量的数学函数库。以下是对NumPy的一些关键特性的介绍:

核心功能

  1. 多维数组对象(ndarray):

    • NumPy的核心是其强大的多维数组对象ndarray。这个对象比Python内置的列表(list)更高效,尤其是在处理大量数据时。
    • 支持多种数据类型,包括整数、浮点数、布尔值、复数等。
  2. 广播机制:

    • 允许不同形状的数组在运算时进行对齐,从而避免了显式地复制数据,提升了效率。
  3. 向量化运算:

    • 许多NumPy的操作都是对整个数组进行的,而不是对数组中的每个元素进行循环操作,这种方式称为向量化运算。向量化运算能够极大地提高计算效率。
  4. 丰富的数学函数库:

    • 提供了大量的数学函数,如线性代数、傅里叶变换、随机数生成等。
  5. 高级索引和切片:

    • 支持布尔索引、花式索引等高级索引操作,使得数据操作更加灵活和方便。

安装

可以通过以下命令安装NumPy:

pip install numpy

查看Pytorch版本,查看Pytorch是否支持GPU运算

import torch
print(torch.__version__)  # 输出: 1.14.0a0+44dac51
print(torch.cuda.is_available())  # 输出: True
  • 输出解释:Pytorch版本为1.14.0a0+44dac51,支持GPU运算。

检查NumPy版本

import numpy as np
print(np.__version__)  # 输出: 1.22.2
  • 输出解释:NumPy版本为1.22.2

NumPy 的维度

在 NumPy 中,数组是一个多维的、同质的数据容器。数组的维度(dimension)是指数组的轴(axis)数目。

维度的基本概念

  1. 轴(Axis):NumPy 数组的每一个维度称为一个轴。轴的编号从 0 开始。例如,对于一个二维数组,轴 0 是行方向,轴 1 是列方向。

示例与解释

一维数组
import numpy as np

arr_1d = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr_1d)
print("形状:", arr_1d.shape)
print("维度:", arr_1d.ndim)
print("元素个数:", arr_1d.size)

输出:

一维数组: [1 2 3 4 5]
形状: (5,)
维度: 1
元素个数: 5
  • 解释arr_1d 是一个一维数组,形状为 (5,),表示它有 5 个元素。维度数 ndim 为 1。
二维数组
import numpy as np

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print("二维数组:\n", arr_2d)
print("形状:", arr_2d.shape)
print("维度:", arr_2d.ndim)
print("元素个数:", arr_2d.size)

输出:

二维数组:
 [[1 2 3]
  [4 5 6]]
形状: (2, 3)
维度: 2
元素个数: 6
  • 解释arr_2d 是一个二维数组,形状为 (2, 3),表示它有 2 行 3 列。维度数 ndim 为 2。
三维数组
import numpy as np

arr_3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print("三维数组:\n", arr_3d)
print("形状:", arr_3d.shape)
print("维度:", arr_3d.ndim)
print("元素个数:", arr_3d.size)

输出:

三维数组:
 [[[ 1  2  3]
   [ 4  5  6]]

  [[ 7  8  9]
   [10 11 12]]]
形状: (2, 2, 3)
维度: 3
元素个数: 12
  • 解释arr_3d 是一个三维数组,形状为 (2, 2, 3),表示它有 2 个 2x3 的二维数组。维度数 ndim 为 3。

NumPy的多维数组对象(ndarray)创建

NumPy的多维数组对象(ndarray)是其核心数据结构,支持高效的数组操作。创建ndarray的方法多种多样,以下是一些常用的方法:

1. 从Python列表或元组创建

import numpy as np

# 从列表创建一维数组
array_1d = np.array([1, 2, 3, 4])
print(array_1d)  # 输出: [1 2 3 4]

# 从嵌套列表创建二维数组
array_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(array_2d)  # 输出: [[1 2 3]
                #       [4 5 6]]

# 从元组创建数组
array_from_tuple = np.array((1, 2, 3))
print(array_from_tuple)  # 输出: [1 2 3]

c = np.array([91, 72, 63, 74, 5], ndmin =  2)
print(c)  # 输出: [[91 72 63 74  5]]

d = np.array([15,  26,  38], dtype = complex)
print(d)  # 输出: [15.+0.j 26.+0.j 38.+0.j]

2. 使用内置的函数创建

2.1. 创建全零数组
# 创建一个3x3的全零数组
zeros_array = np.zeros((3, 3))
print(zeros_array)
# 输出:
# [[0. 0. 0.]
#  [0. 0. 0.]
#  [0. 0. 0.]]
2.2. 创建全一数组
# 创建一个2x4的全一数组
ones_array = np.ones((2, 4))
print(ones_array)
# 输出:
# [[1. 1. 1. 1.]
#  [1. 1. 1. 1.]]
2.3. 创建单位矩阵(对角线为1,其余为0)
# 创建一个3x3的单位矩阵
identity_matrix = np.eye(3)
print(identity_matrix)
# 输出:
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]
2.4. 创建未初始化的数组
# 创建一个2x3的未初始化数组(数组中的值是内存中的随机值)
empty_array = np.empty((2, 3))
print(empty_array)
# 输出:
# [[0.000e+000 0.000e+000 0.000e+000]
#  [0.000e+000 0.000e+000 0.000e+000]]

3. 使用数值范围创建

3.1. 使用arange函数
# 创建一个包含0到9的数组
range_array = np.arange(10)
print(range_array)  # 输出: [0 1 2 3 4 5 6 7 8 9]

# 创建一个包含0到10,步长为2的数组
step_array = np.arange(0, 10, 2)
print(step_array)  # 输出: [0 2 4 6 8]
3.2. 使用linspace函数
# 创建一个包含0到1之间的5个均匀分布的数值的数组
linspace_array = np.linspace(0, 1, 5)
print(linspace_array)  # 输出: [0.   0.25 0.5  0.75 1. ]

4. 使用随机数创建

4.1. 使用random.rand函数
# 创建一个2x3的数组,包含0到1之间的随机浮点数
random_array = np.random.rand(2, 3)
print(random_array)
# 输出:
# [[0.5488135  0.71518937 0.60276338]
#  [0.54488318 0.4236548  0.64589411]]
4.2. 使用random.randint函数
# 创建一个2x3的数组,包含1到10之间的随机整数
random_int_array = np.random.randint(1, 10, (2, 3))
print(random_int_array)
# 输出:
# [[3 7 9]
#  [2 4 1]]

5. 创建特定形状的数组

5.1. 使用reshape函数
# 创建一个包含0到11的数组,并将其重塑为3x4的数组
reshaped_array = np.arange(12).reshape(3, 4)
print(reshaped_array)
# 输出:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

通过这些方法,您可以根据需要创建各种形状和类型的ndarray,以便高效地进行数据处理和科学计算。

NumPy的ndarray的运算操作

好的,以下是去掉了广播机制部分的NumPy ndarray运算的介绍:


NumPy的ndarray对象支持丰富的运算操作,包括基本的算术运算、逻辑运算、统计运算、线性代数运算等。这些运算大多是向量化的,即在整个数组上进行操作,而不是在数组的每个元素上逐个操作,从而提高了计算效率。以下是对NumPy ndarray运算的一些介绍和示例:

1. 基本算术运算

NumPy支持对数组进行基本的算术运算,包括加、减、乘、除、幂运算等。

import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([10, 20, 30, 40])

# 加法
print(a + b)  # 输出: [11 22 33 44]

# 减法
print(a - b)  # 输出: [ -9 -18 -27 -36]

# 乘法
print(a * b)  # 输出: [ 10  40  90 160]

# 除法
print(a / b)  # 输出: [0.1 0.1 0.1 0.1]

# 幂运算
print(a ** 2)  # 输出: [ 1  4  9 16]

2. 统计运算

NumPy提供了丰富的统计运算函数,例如求和、均值、标准差、最小值、最大值等。

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

# 求和
print(a.sum())  # 输出: 15

# 均值
print(a.mean())  # 输出: 3.0

# 标准差
print(a.std())  # 输出: 1.4142135623730951

# 最小值
print(a.min())  # 输出: 1

# 最大值
print(a.max())  # 输出: 5

3. 逻辑运算

NumPy支持对数组进行逻辑运算,例如与、或、非等操作。

a = np.array([True, False, True])
b = np.array([False, False, True])

# 与运算
print(np.logical_and(a, b))  # 输出: [False False  True]

# 或运算
print(np.logical_or(a, b))  # 输出: [ True False  True]

# 非运算
print(np.logical_not(a))  # 输出: [False  True False]

4. 比较运算

NumPy支持对数组进行比较运算,返回布尔数组。

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

# 大于
print(a > b)  # 输出: [False False  True  True]

# 小于
print(a < b)  # 输出: [ True  True False False]

# 等于
print(a == b)  # 输出: [False False False False]

5. 线性代数运算

NumPy提供了线性代数运算的函数,例如矩阵乘法、矩阵转置、逆矩阵、特征值等。

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵乘法
print(np.dot(A, B))
# 输出:
# [[19 22]
#  [43 50]]

# 矩阵转置
print(A.T)
# 输出:
# [[1 3]
#  [2 4]]

# 逆矩阵
print(np.linalg.inv(A))
# 输出:
# [[-2.   1. ]
#  [ 1.5 -0.5]]

# 特征值
eigvals, eigvecs = np.linalg.eig(A)
print(eigvals)  # 输出: [-0.37228132  5.37228132]
print(eigvecs)
# 输出:
# [[-0.82456484 -0.41597356]
#  [ 0.56576746 -0.90937671]]

6. 聚合运算

NumPy提供了多种聚合运算函数,例如summeanstdminmax等,可以在指定轴上进行聚合运算。

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

# 沿轴0(列)求和
print(a.sum(axis=0))  # 输出: [5 7 9]

# 沿轴1(行)求和
print(a.sum(axis=1))  # 输出: [ 6 15]

7. 特殊运算示例

7.1 reciprocal函数

reciprocal函数用于计算数组中每个元素的倒数。

import numpy as np
s = np.array([888, 1000, 20, 0.1])
print('原数组是:')
print(s)  # 输出: [8.88e+02 1.00e+03 2.00e+01 1.00e-01]
print('*'*20)
print('调用reciprocal函数:')
print(np.reciprocal(s))  # 输出: [1.12612613e-03 1.00000000e-03 5.00000000e-02 1.00000000e+01]
7.2 power函数

power函数用于计算数组中每个元素的幂。

import numpy as np
s = np.array([2, 4, 8])
print('原数组是;')
print(s)  # 输出: [2 4 8]
print('*'*20)
print('调用power函数:')
print(np.power(s, 2))  # 输出: [ 4 16 64]
print('*'*20)
print('power之后数组:')
w = np.array([1, 2, 3])
print(w)  # 输出: [1 2 3]
print('*'*20)
print('再次调用power函数:')
print(np.power(s, w))  # 输出: [  2  16 512]
7.3 mod函数

modremainder函数用于计算数组中每个元素的取模。

import numpy as np
s = np.array([3, 6, 9])
w = np.array([2, 4, 8])
print('第一个数组:')
print(s)  # 输出: [3 6 9]
print('*'*20)
print('第二个数组:')
print(w)  # 输出: [2 4 8]
print('*'*20)
print('调用mod()函数:')
print(np.mod(s, w))  # 输出: [1 2 1]
print('*'*20)
print('调用remainder()函数:')
print(np.remainder(s, w))  # 输出: [1 2 1]
7.4 三角函数

NumPy提供了多种三角函数,如sincostan等。

import numpy as np
a = np.array([0, 30, 45, 60, 90])
print('不同角度的正弦值:')
print(np.sin(a * np.pi / 180))  # 输出: [0.         0.5        0.70710678 0.8660254  1.        ]
print('*'*20)
print('数组中角度的余弦值:')
print(np.cos(a * np.pi / 180))  # 输出: [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01 6.12323400e-17]
print('*'*20)
print('数组中角度的正切值:')
print(np.tan(a * np.pi / 180))  # 输出: [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00 1.63312394e+16]
7.5 反三角函数

NumPy还提供了反三角函数,如arcsinarccosarctan等。

import numpy as np
a = np.array([0, 30, 45, 60, 90])
print('含有正弦值的数组:')
sin = np.sin(a * np.pi / 180)
print(sin)  # 输出: [0.         0.5        0.70710678 0.8660254  1.        ]
print('*'*20)
print('计算角度的反正弦,返回值以弧度为单位:')
inv = np.arcsin(sin)
print(inv)  # 输出: [0.         0.52359878 0.78539816 1.04719755 1.57079633]
print('*'*20)
print('通过转化为角度制来检查结果:')
print(np.degrees(inv))  # 输出: [ 0. 30. 45. 60. 90.]
print('*'*20)
print('arccos 和 arctan 函数行为类似:')
cos = np.cos(a * np.pi / 180)
print(cos)  # 输出: [1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01 6.12323400e-17]
print('*'*20)
print('反余弦:')
inv = np.arccos(cos)
print(inv)  # 输出: [0.         0.52359878 0.78539816 1.04719755 1.57079633]
print('*'*20)
print('角度制单位:')
print(np.degrees(inv))  # 输出: [ 0. 30. 45. 60. 90.]
print('*'*20)
print('tan 函数:')
tan = np.tan(a * np.pi / 180)
print(tan)  # 输出: [0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00 1.63312394e+16]
print('*'*20)
print('反正切:')
inv = np.arctan(tan)
print(inv)  # 输出: [0.         0.52359878 0.78539816 1.04719755 1.57079633]
print('*'*20)
print('角度制单位:')
print(np.degrees(inv))  # 输出: [ 0. 30. 45. 60. 90.]
7.6 around函数

around函数用于对数组中的元素进行四舍五入。

import numpy as np
a = np.array([100.0, 100.5, 123, 0.876, 76.998])
print('原数组:')
print(a)  # 输出: [100.    100.5   123.      0.876  76.998]
print('*'*20)
print('舍入后:')
print(np.around(a))  # 输出: [100. 100. 123.   1.  77.]
print(np.around(a, decimals=1))  # 输出: [100.  100.5 123.    0.9  77. ]
print(np.around(a, decimals=-1))  # 输出: [100. 100. 120.   0.  80.]
7.7 floor函数

floor函数用于向下取整。

import numpy as np
s = np.array([-9999.7, 100333.5, -23340.2, 0.987, 10.88888])
print('提供的数组:')
print(s)  # 输出: [-9.999700e+03  1.003335e+05 -2.334020e+04  9.870000e-01  1.088888e+01]
print('*'*20)
print('修改后的数组:')
print(np.floor(s))  # 输出: [-1.00000e+04  1.00333e+05 -2.33410e+04  0.00000e+00  1.00000e+01]
7.8 ceil函数

ceil函数用于向上取整。

import numpy as np
s = np.array([-100.3, 18.98, -0.49999, 0.563, 10])
print('提供的数组:')
print(s)  # 输出: [-100.3       18.98      -0.49999    0.563     10.     ]
print('*'*20)
print('修改后的数组:')
print(np.ceil(s))  # 输出: [-100.   19.   -0.    1.   10.]

通过这些运算,NumPy提供了强大的数据处理和计算能力,使得科学计算和数据分析变得更加高效和便捷。

NumPy的广播机制介绍

NumPy的广播机制是一种强大的功能,允许不同形状的数组在一起进行算术运算。广播机制能够在不显式复制数据的情况下,对形状不匹配的数组进行对齐,从而提高计算效率。

广播机制的基本规则

广播机制的核心规则如下:

  1. 数组维度对齐:如果两个数组的维度不同,较小维度的数组会在左侧进行扩展,以匹配较大维度的数组。
  2. 形状对齐:从后往前比较两个数组的形状。如果两个维度的大小相同,或者其中一个维度的大小为1,则认为它们是兼容的,可以进行广播。
  3. 维度扩展:如果一个数组的某个维度大小为1,则在计算时会沿着该维度进行复制,以匹配另一个数组的大小。

广播机制的应用示例

示例1:标量与数组的广播
import numpy as np

arr = np.array([1, 2, 3, 4])
scalar = 10

# 标量和数组相加
result = arr + scalar
print(result)  # 输出: [11 12 13 14]

解释:标量 10 被广播为与数组 arr 相同的形状 [10, 10, 10, 10],然后进行逐元素相加。

示例2:一维数组与二维数组的广播
import numpy as np

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

# 一维数组和二维数组相加
result = arr1 + arr2
print(result)

输出:

[[ 5  6  7]
 [ 6  7  8]
 [ 7  8  9]]

解释:一维数组 arr1 的形状是 (3,),二维数组 arr2 的形状是 (3, 1)。通过广播机制,arr1 被扩展为 (3, 3)arr2 被扩展为 (3, 3),然后进行逐元素相加。

示例3:二维数组与三维数组的广播
import numpy as np

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

# 二维数组和三维数组相加
result = arr1 + arr2
print(result)

输出:

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

 [[ 3  4  5]
  [ 6  7  8]]

 [[ 4  5  6]
  [ 7  8  9]]]

解释:二维数组 arr1 的形状是 (2, 3),三维数组 arr2 的形状是 (3, 1, 1)。通过广播机制,arr1 被扩展为 (1, 2, 3),然后复制三次成为 (3, 2, 3)arr2 被扩展为 (3, 2, 3),然后进行逐元素相加。

广播机制的具体步骤

  1. 对齐形状

    • 比较两个数组的形状,从后往前对齐。
    • 如果某个维度不匹配且其中一个维度为1,则可以进行广播。
    • 如果某个维度不匹配且都不为1,则无法进行广播。
  2. 扩展维度

    • 对于维度为1的数组,沿该维度进行复制,直到匹配另一个数组的大小。

广播机制的优势

  • 内存效率:广播机制可以避免显式地复制数据,从而节省内存。
  • 计算效率:广播机制可以在底层进行优化,提高计算速度。
  • 代码简洁:广播机制使得代码更加简洁和易读,减少了显式数据对齐和复制的代码量。

NumPy的广播机制是一种强大的功能,允许不同形状的数组在一起进行算术运算。通过广播机制,可以在不显式复制数据的情况下,对形状不匹配的数组进行对齐,从而提高计算效率。广播机制在数据处理和科学计算中具有广泛的应用,使得NumPy在处理多维数组时更加灵活和高效。

NumPy 数组的形状操作

NumPy 提供了丰富的数组形状操作功能,可以方便地对数组的形状进行调整和变换。这些操作在数据处理和科学计算中非常有用,能够帮助我们更灵活地处理多维数据。

常见的形状操作
  1. reshape:改变数组的形状。
  2. resize:改变数组的形状并修改其大小。
  3. ravel:将多维数组展平为一维数组。
  4. flatten:返回一个一维数组的副本。
  5. transpose:转置数组。
  6. swapaxes:交换数组的两个轴。
  7. expand_dims:扩展数组的形状。
  8. squeeze:从数组的形状中移除单维度。

详细解释和示例

1. reshape:改变数组的形状
import numpy as np

arr = np.arange(12)
print("原数组:\n", arr)

reshaped_arr = arr.reshape(3, 4)
print("改变形状后的数组:\n", reshaped_arr)

输出:

原数组:
 [ 0  1  2  3  4  5  6  7  8  9 10 11]
改变形状后的数组:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
  • 解释reshape 可以将一维数组转换为二维数组,或者将多维数组转换为不同形状的数组,但总元素数必须保持不变。
2. resize:改变数组的形状并修改其大小
import numpy as np

arr = np.arange(12)
print("原数组:\n", arr)

arr.resize(3, 4)
print("改变形状并修改大小后的数组:\n", arr)

输出:

原数组:
 [ 0  1  2  3  4  5  6  7  8  9 10 11]
改变形状并修改大小后的数组:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
  • 解释resize 改变数组的形状并修改其大小,如果新大小比原大小大,则用零填充。
3. ravel:将多维数组展平为一维数组
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("原数组:\n", arr)

flattened_arr = arr.ravel()
print("展平后的数组:\n", flattened_arr)

输出:

原数组:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
展平后的数组:
 [1 2 3 4 5 6 7 8 9]
  • 解释ravel 将多维数组展平为一维数组,但返回的是原数组的视图。
4. flatten:返回一个一维数组的副本
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("原数组:\n", arr)

flattened_arr = arr.flatten()
print("展平后的数组副本:\n", flattened_arr)

输出:

原数组:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
展平后的数组副本:
 [1 2 3 4 5 6 7 8 9]
  • 解释flatten 返回一个一维数组的副本,与 ravel 不同,flatten 创建的是数组的副本。
5. transpose:转置数组
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
print("原数组:\n", arr)

transposed_arr = arr.transpose()
print("转置后的数组:\n", transposed_arr)

输出:

原数组:
 [[1 2 3]
 [4 5 6]]
转置后的数组:
 [[1 4]
 [2 5]
 [3 6]]
  • 解释transpose 将数组的行和列互换,返回转置后的数组。
6. swapaxes:交换数组的两个轴
import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])
print("原数组:\n", arr)

swapped_arr = arr.swapaxes(0, 1)
print("交换轴后的数组:\n", swapped_arr)

输出:

原数组:
 [[1 2 3]
 [4 5 6]]
交换轴后的数组:
 [[1 4]
 [2 5]
 [3 6]]
  • 解释swapaxes 交换数组的两个轴,例如从 (0, 1) 变为 (1, 0)。
7. expand_dims:扩展数组的形状
import numpy as np

arr = np.array([1, 2, 3])
print("原数组:\n", arr)

expanded_arr = np.expand_dims(arr, axis=0)
print("扩展形状后的数组:\n", expanded_arr)

输出:

原数组:
 [1 2 3]
扩展形状后的数组:
 [[1 2 3]]
  • 解释expand_dims 在指定轴上扩展数组的形状,例如在0轴上扩展。
8. squeeze:从数组的形状中移除单维度
import numpy as np

arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print("原数组:\n", arr)

squeezed_arr = np.squeeze(arr, axis=0)
print("移除单维度后的数组:\n", squeezed_arr)

输出:

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

  [[5 6]
   [7 8]]]
移除单维度后的数组:
 [[1 2]
  [3 4]
 [5 6]
 [7 8]]
  • 解释squeeze 从数组的形状中移除单维度,例如从 (1, 4, 2) 变为 (4, 2)。

总结

通过上述形状操作,NumPy 数组可以灵活地进行调整和变换,以适应不同的数据处理需求。这些操作在机器学习、数据分析、科学计算等领域中都有广泛的应用。

NumPy数组的切片操作

NumPy数组的切片操作允许用户获取数组的子集。切片操作的语法与Python内置的列表切片类似,但NumPy数组可以是多维的,因此切片操作也可以应用于多维数组。

基础切片操作

一维数组切片

切片的基本语法是 start:stop:step,其中:

  • start 是切片的起始索引(包含)。
  • stop 是切片的结束索引(不包含)。
  • step 是切片的步长。
import numpy as np

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

# 获取从索引2到索引5的元素 (不包含索引5)
print(a[2:5])  # 输出: [2 3 4]

# 获取从索引0到索引8的元素,步长为2
print(a[0:8:2])  # 输出: [0 2 4 6]

# 获取从索引1到末尾的元素
print(a[1:])  # 输出: [1 2 3 4 5 6 7 8 9]

# 获取从开始到索引5的元素
print(a[:5])  # 输出: [0 1 2 3 4]

# 获取整个数组的元素
print(a[:])  # 输出: [0 1 2 3 4 5 6 7 8 9]
二维数组切片

对于二维数组,切片操作可以分别应用于每个维度。语法是 array[row_start:row_stop:row_step, col_start:col_stop:col_step]

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

# 获取第1行到第3行,第1列到第3列的子数组
print(b[1:3, 1:3])
# 输出:
# [[ 5  6]
#  [ 9 10]]

# 获取第2行的所有元素
print(b[2, :])  # 输出: [ 8  9 10 11]

# 获取所有行的第2列
print(b[:, 2])  # 输出: [ 2  6 10 14]

三维数组切片

对于三维数组,切片操作可以分别应用于每个维度。语法是 array[dim1_start:dim1_stop:dim1_step, dim2_start:dim2_stop:dim2_step, dim3_start:dim3_stop:dim3_step]

c = np.array([[[ 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]]])

# 获取第0维度的第1个子数组
print(c[1])
# 输出:
# [[ 9 10 11]
#  [12 13 14]
#  [15 16 17]]

# 获取第0维度的第1个子数组的第1行
print(c[1, 1])
# 输出: [12 13 14]

# 获取第0维度的第1个子数组的第1行的第1个元素
print(c[1, 1, 1])  # 输出: 13

# 获取第0维度的第0个和第1个子数组,第1维度的第1行和第2行,第2维度的第0个和第2个元素
print(c[0:2, 1:3, 0:3:2])
# 输出:
# [[[ 3  5]
#   [ 6  8]]
#
#  [[12 14]
#   [15 17]]]

高级切片操作

布尔索引

布尔索引允许你基于条件筛选数组中的元素。

d = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

# 获取所有大于5的元素
print(d[d > 5])  # 输出: [6 7 8 9]
花式索引

花式索引允许你使用整数数组进行索引。

e = np.array([10, 20, 30, 40, 50])

# 使用整数数组进行索引
print(e[[0, 2, 4]])  # 输出: [10 30 50]
混合索引

你可以混合使用基本切片、布尔索引和花式索引。

f = np.array([[ 0,  1,  2,  3],
              [ 4,  5,  6,  7],
              [ 8,  9, 10, 11],
              [12, 13, 14, 15]])

# 获取第1行和第3行的第0列和第2列的元素
print(f[[1, 3], [0, 2]])  # 输出: [ 4 14]

# 获取第0行到第2行的所有元素,步长为2
print(f[0:3:2, :])  # 输出: [[ 0  1  2  3]
                   #        [ 8  9 10 11]]

三维数组切片的具体示例

g = np.array([[[ 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]]])

# 获取第1维度的第1个子数组的第1行的所有元素
print(g[1, 1, :])  # 输出: [12 13 14]

# 获取第0维度的第0个和第1个子数组,第1维度的第1行和第2行,第2维度的所有元素
print(g[0:2, 1:3, :])
# 输出:
# [[[ 3  4  5]
#   [ 6  7  8]]
#
#  [[12 13 14]
#   [15 16 17]]]

# 获取第0维度的所有子数组,第1维度的第0行和第2行,第2维度的第1个元素
print(g[:, [0, 2], 1])
# 输出:
# [[ 1  7]
#  [10 16]
#  [19 25]]

通过这些示例,你可以看到NumPy数组的切片操作非常强大且灵活,能够满足多种数据处理需求。特别是对于三维数组,切片操作可以让你方便地获取多维数据的子集。

Numpy中的轴及沿轴操作

在 NumPy 中,很多操作(如求和、均值等)都可以沿指定的轴进行。为了更好地理解这些操作,我们需要深入了解轴的概念及其在多维数组中的应用。

基本概念

  • 轴(Axis):NumPy 数组的每一个维度称为一个轴。轴的编号从 0 开始。
  • 沿轴操作:沿指定轴进行操作时,NumPy 会在该轴方向上进行计算,而保留其他轴的结构。

示例与解释

示例:二维数组的轴操作
import numpy as np

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print("原数组:\n", arr_2d)
  • 二维数组arr_2d 是一个 2x3 的数组,具有两个轴:
    • 轴 0(行方向):包含 [1, 2, 3][4, 5, 6] 两行。
    • 轴 1(列方向):包含 [1, 4][2, 5][3, 6] 三列。
沿轴 0 求和
sum_axis0 = np.sum(arr_2d, axis=0)
print("沿轴0求和:", sum_axis0)
  • 计算过程
    • 沿轴 0 进行求和时,NumPy 会在行方向上对每一列的元素进行相加。
    • 计算过程:
      • 第一列:1 + 4 = 5
      • 第二列:2 + 5 = 7
      • 第三列:3 + 6 = 9
    • 结果:[5, 7, 9]

输出:

沿轴0求和: [5 7 9]
沿轴 1 求和
sum_axis1 = np.sum(arr_2d, axis=1)
print("沿轴1求和:", sum_axis1)
  • 计算过程
    • 沿轴 1 进行求和时,NumPy 会在列方向上对每一行的元素进行相加。
    • 计算过程:
      • 第一行:1 + 2 + 3 = 6
      • 第二行:4 + 5 + 6 = 15
    • 结果:[6, 15]

输出:

沿轴1求和: [ 6 15]
示例:三维数组的轴操作
arr_3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print("原三维数组:\n", arr_3d)
  • 三维数组arr_3d 是一个 2x2x3 的数组,具有三个轴:
    • 轴 0(页方向):包含两个 2x3 的二维数组。
    • 轴 1(行方向):每页包含两行。
    • 轴 2(列方向):每行包含三列。
沿轴 0 求均值
mean_axis0 = np.mean(arr_3d, axis=0)
print("沿轴0求均值:\n", mean_axis0)
  • 计算过程
    • 沿轴 0 进行求均值时,NumPy 会在页方向上对每个位置的元素进行求均值。
    • 计算过程:
      • 第一页和第二页的第一个位置:(1 + 7) / 2 = 4
      • 第一页和第二页的第二个位置:(2 + 8) / 2 = 5
      • 第一页和第二页的第三个位置:(3 + 9) / 2 = 6
      • 以此类推…
    • 结果:
      [[ 4.  5.  6.]
       [ 7.  8.  9.]]
      

输出:

沿轴0求均值:
 [[ 4.  5.  6.]
  [ 7.  8.  9.]]
沿轴 1 求均值
mean_axis1 = np.mean(arr_3d, axis=1)
print("沿轴1求均值:\n", mean_axis1)
  • 计算过程
    • 沿轴 1 进行求均值时,NumPy 会在行方向上对每一页的每一列进行求均值。
    • 计算过程:
      • 第一页的第一列和第二列:(1 + 4) / 2 = 2.5
      • 第一页的第二列和第三列:(2 + 5) / 2 = 3.5
      • 第一页的第三列和第四列:(3 + 6) / 2 = 4.5
      • 以此类推…
    • 结果:
      [[ 2.5  3.5  4.5]
       [ 8.5  9.5 10.5]]
      

输出:

沿轴1求均值:
 [[ 2.5  3.5  4.5]
  [ 8.5  9.5 10.5]]
沿轴 2 求均值
mean_axis2 = np.mean(arr_3d, axis=2)
print("沿轴2求均值:\n", mean_axis2)
  • 计算过程
    • 沿轴 2 进行求均值时,NumPy 会在列方向上对每一行的元素进行求均值。
    • 计算过程:
      • 第一页的第一行:(1 + 2 + 3) / 3 = 2
      • 第一页的第二行:(4 + 5 + 6) / 3 = 5
      • 第二页的第一行:(7 + 8 + 9) / 3 = 8
      • 第二页的第二行:(10 + 11 + 12) / 3 = 11
    • 结果:
      [[ 2.  5.]
       [ 8. 11.]]
      

输出:

沿轴2求均值:
 [[ 2.  5.]
  [ 8. 11.]]

通过上述示例,我们可以看到沿指定轴进行操作的计算过程。无论是求和、均值还是其他操作,NumPy 都允许我们指定轴进行计算,从而灵活地处理多维数组的数据。这种灵活性使得 NumPy 在数据处理和科学计算中非常强大和高效。

NumPy数据类型(dtype)

NumPy支持多种数据类型(dtype),这些数据类型允许用户在数组中存储不同类型的数据。选择合适的数据类型可以优化内存使用和计算效率。以下是NumPy中常用的数据类型及其应用场合:

常用数据类型

  1. 整数类型(Integer Types)

    • int8: 8位有符号整数,范围从 -128 到 127。
    • int16: 16位有符号整数,范围从 -32768 到 32767。
    • int32: 32位有符号整数,范围从 -2147483648 到 2147483647。
    • int64: 64位有符号整数,范围从 -9223372036854775808 到 9223372036854775807。

    应用场合: 当需要存储整数数据时,根据数据范围选择合适的整数类型。例如,int8适用于存储范围较小的整数数据,可以节省内存。

  2. 无符号整数类型(Unsigned Integer Types)

    • uint8: 8位无符号整数,范围从 0 到 255。
    • uint16: 16位无符号整数,范围从 0 到 65535。
    • uint32: 32位无符号整数,范围从 0 到 4294967295。
    • uint64: 64位无符号整数,范围从 0 到 18446744073709551615。

    应用场合: 当数据不包含负数且需要更大的范围时使用无符号整数。例如,图像处理中的像素值通常使用uint8类型。

  3. 浮点数类型(Floating Point Types)

    • float16: 16位半精度浮点数。
    • float32: 32位单精度浮点数。
    • float64: 64位双精度浮点数(NumPy默认浮点数类型)。

    应用场合: 当需要存储实数数据时使用浮点数类型。float32适用于内存有限但精度要求不高的场合,而float64适用于需要较高精度的计算。

  4. 复数类型(Complex Types)

    • complex64: 32位实数和32位虚数组成的复数。
    • complex128: 64位实数和64位虚数组成的复数(NumPy默认复数类型)。

    应用场合: 当需要处理包含复数的数学计算时使用复数类型。例如,信号处理和量子计算中常用复数表示。

  5. 布尔类型(Boolean Type)

    • bool: 布尔类型,存储TrueFalse

    应用场合: 用于条件判断和逻辑操作。例如,布尔数组可以用于掩码操作和条件筛选。

  6. 字符串类型(String Types)

    • string_: 固定长度字符串类型。
    • unicode_: 固定长度的Unicode字符串类型。

    应用场合: 当需要存储文本数据时使用字符串类型。string_适用于ASCII字符,而unicode_适用于多语言文本。

  7. 日期时间类型(Datetime Types)

    • datetime64: 日期时间类型,表示日期和时间。
    • timedelta64: 时间差类型,表示两个日期时间之间的时间差。

    应用场合: 当需要处理时间序列数据时使用日期时间类型。例如,金融数据分析和时间序列预测中常用。

数据类型示例

import numpy as np

# 创建不同数据类型的数组
int_array = np.array([1, 2, 3], dtype=np.int32)
float_array = np.array([1.0, 2.0, 3.0], dtype=np.float64)
complex_array = np.array([1+2j, 3+4j], dtype=np.complex128)
bool_array = np.array([True, False, True], dtype=np.bool_)
str_array = np.array(['a', 'b', 'c'], dtype=np.string_)
unicode_array = np.array(['a', 'b', 'c'], dtype=np.unicode_)
datetime_array = np.array(['2023-01-01', '2023-01-02'], dtype=np.datetime64)
timedelta_array = np.array([1, 2, 3], dtype=np.timedelta64)

# 打印数组和数据类型
print(int_array, int_array.dtype)  # 输出: [1 2 3] int32
print(float_array, float_array.dtype)  # 输出: [1. 2. 3.] float64
print(complex_array, complex_array.dtype)  # 输出: [1.+2.j 3.+4.j] complex128
print(bool_array, bool_array.dtype)  # 输出: [ True False  True] bool
print(str_array, str_array.dtype)  # 输出: [b'a' b'b' b'c'] |S1
print(unicode_array, unicode_array.dtype)  # 输出: ['a' 'b' 'c'] <U1
print(datetime_array, datetime_array.dtype)  # 输出: ['2023-01-01' '2023-01-02'] datetime64[D]
print(timedelta_array, timedelta_array.dtype)  # 输出: [1 2 3] timedelta64[D]

通过合理选择数据类型,可以优化内存使用和计算效率,从而提升程序性能。不同应用场合需要选择合适的数据类型,以满足特定需求。

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NumPy是Python中一个非常核心且不可或缺的科学计算库,它提供了高效的数组操作和数学函数,使得数据处理变得简单且快速。NumPy的核心是`numpy.ndarray`,这是一个多维数组对象,它可以存储各种数据类型,并支持广播机制、切片、索引等操作。 NumPy的主要特点包括: 1. **数组对象**:NumPy数组是带有维度的大型数组,类似于R语言中的向量或矩阵,非常适合处理大量数据。 2. **数据类型**:NumPy数组支持固定大小的数据类型,这使得内存管理高效,避免了不必要的类型转换。 3. **数学运算**:内置了大量的数学函数,可以直接对数组进行运算,如加减乘除、三角函数、指数对数等。 4. ** broadcasting**:NumPy的广播功能允许不同形状的数组之间进行元素级别的运算,简化了操作过程。 5. **兼容性**:NumPy与其他Python科学计算库(如Pandas, SciPy)高度兼容,是数据处理和分析的基础。 使用NumPy通常包括以下步骤: - **安装**:如果你还没安装,可以通过pip(Python包管理器)命令 `pip install numpy` 来安装。 - **导入模块**:在Python脚本中,使用 `import numpy as np` 导入NumPy,并用`np`作为别名来调用函数和方法。 - **创建数组**:可以使用`np.array()`函数创建数组,或使用特殊构造函数如`np.zeros()`、`np.ones()`等。 - **数组操作**:例如,对数组进行索引、切片、排序、统计等操作,以及使用`np.dot()`或`@`符号进行矩阵运算。 - **函数应用**:使用`np.apply_along_axis()`等函数对数组沿着指定轴进行操作。 以下是一些常见NumPy操作的例子: ```python import numpy as np # 创建数组 arr = np.array([1, 2, 3, 4, 5]) print(arr) # 数组操作 print(arr[2:4]) # 切片操作 print(np.sum(arr)) # 求和 # 数学函数 print(np.sin(arr)) # 广播示例 arr1 = np.array([1, 2]) arr2 = np.array([3, 4, 5]) print(arr1 + arr2) # 两个不同形状数组的相加 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值