第五篇:NumPy 的 “文件魔法”:数据读写与存储 (应用篇)
开篇提问:
考虑这样一个实际场景:你花费数小时运行复杂的模拟,生成了庞大的 科学数据集,例如气候模型输出或基因测序结果。 这些数据存储在 NumPy 数组中,占据了大量的内存。 现在,你需要 关闭程序,稍后继续分析,或者 将数据分享给其他研究人员。 手动复制粘贴数据显然是不现实的。 我们需要一种 高效、可靠 的方法,将 NumPy 数组 保存到文件,并在需要时 快速加载 回来。
NumPy 提供了强大的 文件输入/输出 (I/O) 功能,专门用于处理 NumPy 数组数据的 读写和存储。 掌握这些功能,你就能轻松地 持久化你的数据, 高效地加载和共享数据,从而构建更完整、更实用的数据分析工作流程。 今天,我们就来探索 NumPy 的 “文件魔法”,学习如何高效地进行 NumPy 数组的数据读写与存储。
核心概念讲解 (费曼式解释):
-
保存 NumPy 数组到文件: “持久化你的数据成果”
NumPy 提供了多种函数,可以将 NumPy 数组 保存到不同格式的文件 中。 选择合适的文件格式取决于你的需求,例如 数据大小、读写速度、是否需要人眼可读、是否需要跨平台共享 等。 常用的 NumPy 数组保存函数包括:
-
np.save(file, arr)
: 保存为 NumPy 二进制文件 (.npy)np.save()
函数将单个 NumPy 数组 保存为.npy
格式的二进制文件。.npy
文件格式是 NumPy 专用的二进制格式,它以 高效、快速 的方式存储 NumPy 数组的 数据、形状和数据类型 等信息。.npy
文件 不适合人眼阅读,但 非常适合 NumPy 数组的持久化存储和快速加载。import numpy as np # 创建一个 NumPy 数组 data_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print("要保存的 NumPy 数组:\n", data_array) # 1. 保存数组到 .npy 文件 (二进制格式) file_path_npy = "data_array.npy" # 指定 .npy 文件路径 np.save(file_path_npy, data_array) # 保存数组到文件 print(f"\n数组已保存到 .npy 文件: {file_path_npy}") # 你可以尝试用文本编辑器打开 .npy 文件,会看到乱码,因为它是二进制格式,不适合人眼阅读
代码解释:
np.save(file, arr, allow_pickle=True, fix_imports=True)
:file
: 文件路径或文件对象,指定要保存的文件名或文件对象。 如果提供文件路径字符串,NumPy 会自动打开文件进行写入。arr
: 要保存的 NumPy 数组。allow_pickle=True
: 默认值True
。 允许使用 Python 的pickle
机制保存对象数组 (包含 Python 对象的数组)。 对于纯数值数组,可以设置为False
以提高安全性。fix_imports=True
: 默认值True
。 尝试修复 Python 3 和 Python 2 之间导入兼容性问题。
-
np.savez(file, *arrays, **kwds)
: 保存多个数组到压缩的 NumPy 归档文件 (.npz)np.savez()
函数可以将 多个 NumPy 数组 压缩 后 保存到一个.npz
格式的归档文件 中。.npz
文件实际上是一个 zip 压缩文件,里面包含了多个.npy
文件,每个.npy
文件对应一个保存的数组。.npz
文件 可以有效地节省存储空间,并且可以 方便地一次性加载多个数组。import numpy as np # 创建多个 NumPy 数组 array_a = np.array([1, 2, 3]) array_b = np.array([[10, 20], [30, 40]]) array_c = np.array(['apple', 'banana', 'cherry']) print("要保存的数组 array_a:\n", array_a) print("\n要保存的数组 array_b:\n", array_b) print("\n要保存的数组 array_c:\n", array_c) # 1. 保存多个数组到 .npz 文件 (压缩归档格式) file_path_npz = "multiple_arrays.npz" # 指定 .npz 文件路径 np.savez(file_path_npz, array1=array_a, array2=array_b, array3=array_c) # 使用关键字参数命名数组 print(f"\n多个数组已保存到 .npz 文件: {file_path_npz}") # .npz 文件可以使用压缩软件 (如 7-Zip, WinRAR) 打开,查看里面的 .npy 文件
代码解释:
np.savez(file, *arrays, **kwds, compression=None, allow_pickle=True)
:file
: 文件路径或文件对象,指定要保存的.npz
文件名或文件对象。*arrays
: 要保存的 NumPy 数组,可以传递多个数组作为位置参数。**kwds
: 关键字参数,用于 为每个数组指定一个名称。 建议使用关键字参数,为每个数组命名,方便后续加载时按名称访问。 例如array1=array_a, array2=array_b, array3=array_c
。compression=None
: 压缩算法,默认为None
(不压缩)。 可以设置为'gzip'
或'zip'
使用压缩算法,进一步减小文件大小。allow_pickle=True
: 与np.save()
的allow_pickle
参数含义相同。
-
np.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ', encoding=None)
: 保存为文本文件 (.txt, .csv 等)np.savetxt()
函数可以将 NumPy 数组 保存为文本文件,例如.txt
,.csv
等格式。 文本文件 人眼可读, 跨平台兼容性好,可以 方便地与其他程序或工具交换数据。 但文本文件 通常比二进制文件更大,读写速度也较慢。import numpy as np # 创建一个 NumPy 数组 data_array = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6], [7.7, 8.8, 9.9]]) print("要保存的 NumPy 数组 (浮点数):\n", data_array) # 1. 保存数组到 .txt 文件 (默认格式,空格分隔) file_path_txt = "data_array.txt" # 指定 .txt 文件路径 np.savetxt(file_path_txt, data_array) # 保存数组到文件 (默认空格分隔) print(f"\n数组已保存到 .txt 文件 (空格分隔): {file_path_txt}") # 你可以用文本编辑器打开 data_array.txt 文件,查看文本数据 # 2. 保存数组到 .csv 文件 (逗号分隔,指定格式,添加 header 和 footer) file_path_csv = "data_array.csv" # 指定 .csv 文件路径 header_str = "Column1,Column2,Column3" # CSV 文件 header footer_str = "# End of data" # CSV 文件 footer np.savetxt(file_path_csv, data_array, delimiter=',', fmt='%.2f', header=header_str, footer=footer_str, comments='# ') # 保存为 CSV 文件,逗号分隔,保留 2 位小数,添加 header 和 footer print(f"\n数组已保存到 .csv 文件 (逗号分隔, 2 位小数, header, footer): {file_path_csv}") # 你可以用文本编辑器或 Excel 等软件打开 data_array.csv 文件,查看 CSV 格式数据
代码解释:
np.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ', encoding=None)
:fname
: 文件路径或文件对象,指定要保存的文本文件名或文件对象。X
: 要保存的 NumPy 数组。fmt='%.18e'
: 数据格式字符串,用于控制 数值数据的输出格式。 默认值'%.18e'
表示使用科学计数法,保留 18 位有效数字。 可以根据需要修改格式,例如'%d'
(整数),'%.2f'
(浮点数,保留 2 位小数),'%.3f'
(浮点数,保留 3 位小数),'%.5e'
(科学计数法,保留 5 位有效数字) 等。delimiter=' '
: 数据分隔符,用于 分隔不同列的数据。 默认值' '
表示使用空格分隔。 对于 CSV 文件,通常设置为','
(逗号分隔)。 对于 TSV 文件,可以设置为'\t'
(制表符分隔)。newline='\n'
: 换行符,用于 分隔不同行的数据。 默认值'\n'
表示使用换行符。header=''
: 文件头部字符串,用于 添加文件头部注释或列名。 例如,可以设置为"Column1,Column2,Column3"
作为 CSV 文件的列名。footer=''
: 文件尾部字符串,用于 添加文件尾部注释。comments='# '
: 注释前缀字符串,用于 标记注释行。 默认值'# '
表示使用#
作为注释前缀。header
和footer
会作为注释行添加到文件头部和尾部。encoding=None
: 文件编码,用于 指定文本文件的字符编码。 默认值None
表示使用系统默认编码。 常用的编码包括'utf-8'
,'gbk'
等。
-
-
加载 NumPy 数组从文件: “读取并重构你的数据”
与保存数组相对应,NumPy 也提供了多种函数,可以 从不同格式的文件中加载 NumPy 数组。 常用的 NumPy 数组加载函数包括:
-
np.load(file, allow_pickle=True, fix_imports=True, encoding='ASCII')
: 加载 NumPy 二进制文件 (.npy, .npz)np.load()
函数可以 加载.npy
和.npz
格式的 NumPy 二进制文件。 对于.npy
文件,np.load()
会 直接返回保存的 NumPy 数组。 对于.npz
文件,np.load()
会 返回一个类似字典的对象 (NpzFile 对象),你可以 通过数组名称 (保存时指定的关键字参数名称) 来 访问加载的 NumPy 数组。import numpy as np # 1. 加载 .npy 文件 file_path_npy = "data_array.npy" # .npy 文件路径 (假设文件已存在) loaded_array_npy = np.load(file_path_npy) # 加载 .npy 文件 print(".npy 文件加载的数组:\n", loaded_array_npy) print("加载数组的数据类型:", loaded_array_npy.dtype) # 数据类型会被完整保留 # 2. 加载 .npz 文件 (加载多个数组) file_path_npz = "multiple_arrays.npz" # .npz 文件路径 (假设文件已存在) loaded_data_npz = np.load(file_path_npz) # 加载 .npz 文件,返回 NpzFile 对象 print("\n.npz 文件加载的数据 (NpzFile 对象):\n", loaded_data_npz) # <numpy.lib.io.NpzFile object at ...> print("\n.npz 文件包含的数组名称:", loaded_data_npz.files) # ['array1', 'array2', 'array3'] # 通过数组名称访问加载的数组 loaded_array_a = loaded_data_npz['array1'] # 按名称访问数组 loaded_array_b = loaded_data_npz['array2'] loaded_array_c = loaded_data_npz['array3'] print("\n.npz 文件加载的数组 array_a:\n", loaded_array_a) print("\n.npz 文件加载的数组 array_b:\n", loaded_array_b) print("\n.npz 文件加载的数组 array_c:\n", loaded_array_c) # 关闭 NpzFile 对象 (可选,但建议关闭,释放资源) loaded_data_npz.close()
代码解释:
np.load(file, allow_pickle=True, fix_imports=True, encoding='ASCII')
:file
: 文件路径或文件对象,指定要加载的.npy
或.npz
文件名或文件对象。allow_pickle=True
: 与np.save()
的allow_pickle
参数含义相同。 加载包含 Python 对象数组的.npy
或.npz
文件时需要设置为True
。 注意安全风险:加载来自不可信来源的 pickled 数据可能存在安全风险,因为 pickled 数据可以包含任意 Python 代码。 如果加载的文件只包含纯数值数据,可以设置为False
以提高安全性。fix_imports=True
: 与np.save()
的fix_imports
参数含义相同。encoding='ASCII'
: 字符编码,用于 解码 pickled 的字符串数据。 默认值'ASCII'
。 如果 pickled 数据使用了其他编码,需要根据实际情况修改encoding
参数。
NpzFile
对象:np.load()
加载.npz
文件后返回的对象,类似字典,可以通过数组名称 (保存时指定的关键字参数名称) 访问加载的数组。 加载完成后,建议调用NpzFile
对象的close()
方法关闭文件,释放资源。
-
np.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None, like=None)
: 加载文本文件 (.txt, .csv 等)np.loadtxt()
函数可以 从文本文件中加载数据,并转换为 NumPy 数组。np.loadtxt()
可以 灵活地处理各种文本文件格式,例如空格分隔、逗号分隔、制表符分隔等,并且可以 指定数据类型、跳过头部行、选择特定列 等。import numpy as np # 1. 加载 .txt 文件 (空格分隔) file_path_txt = "data_array.txt" # .txt 文件路径 (假设文件已存在) loaded_array_txt = np.loadtxt(file_path_txt) # 加载 .txt 文件 (默认空格分隔) print(".txt 文件加载的数组 (空格分隔):\n", loaded_array_txt) print("加载数组的数据类型:", loaded_array_txt.dtype) # 默认数据类型为 float64 # 2. 加载 .csv 文件 (逗号分隔,跳过 header 和 footer,指定数据类型) file_path_csv = "data_array.csv" # .csv 文件路径 (假设文件已存在,并且包含 header 和 footer) loaded_array_csv = np.loadtxt(file_path_csv, delimiter=',', dtype=np.float32, skiprows=1, skipfooter=1, comments='#') # 加载 CSV 文件,逗号分隔,数据类型 float32,跳过 1 行 header 和 1 行 footer print("\n.csv 文件加载的数组 (逗号分隔, float32, 跳过 header/footer):\n", loaded_array_csv) print("加载数组的数据类型:", loaded_array_csv.dtype) # 数据类型为 float32 (已指定)
代码解释:
np.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes', max_rows=None, like=None)
:fname
: 文件路径或文件对象,指定要加载的文本文件名或文件对象。dtype=<class 'float'>
: 数据类型,用于 指定加载的数据的数据类型。 默认值<class 'float'>
表示加载为浮点数类型。 可以根据实际数据类型修改,例如np.int32
,np.str_
等。comments='#'
: 注释前缀字符串,用于 标记注释行。 默认值'#'
表示以#
开头的行为注释行,会被忽略。delimiter=None
: 数据分隔符,用于 分隔不同列的数据。 默认值None
表示自动检测分隔符 (通常是空格或制表符)。 对于 CSV 文件,设置为','
(逗号分隔)。skiprows=0
: 跳过头部行数,用于 跳过文件头部的注释行或标题行。 默认值0
表示不跳过。skipfooter=0
: 跳过尾部行数,用于 跳过文件尾部的注释行或总结行。 默认值0
表示不跳过。usecols=None
: 要加载的列索引或列索引序列,用于 选择加载文件中的特定列。 默认值None
表示加载所有列。encoding='bytes'
: 文件编码,用于 指定文本文件的字符编码。 默认值'bytes'
表示以字节方式读取。 常用的编码包括'utf-8'
,'gbk'
等。
-
np.genfromtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, skip_header=0, skip_footer=0, converters=None, missing_values=None, filling_values=None, usecols=None, names=None, excludelist=None, deletechars="~
\r\n\t ", replace_space=‘_’, autostrip=False, case_sensitive=True, defaultfmt=‘f%i’, unpack=None, usemask=False, loose=True, invalid_raise=True, max_rows=None, encoding=‘bytes’)`: 更强大的文本文件加载函数np.genfromtxt()
函数是np.loadtxt()
的 更强大、更通用 的版本。np.genfromtxt()
可以 更灵活地处理各种复杂的文本文件,例如 包含缺失值、不同数据类型、不规则分隔符 等的文件。np.genfromtxt()
的功能更全面,但 使用也更复杂,性能可能略低于np.loadtxt()
。 对于简单的文本文件加载,np.loadtxt()
通常足够使用。 对于需要处理复杂文本文件的情况,np.genfromtxt()
是更强大的选择。 这里我们只做简单介绍,具体用法可以查阅 NumPy 文档。
-
-
选择合适的文件格式: “根据需求选择最佳方案”
在 NumPy 数组文件 I/O 中,选择合适的文件格式非常重要,它会影响 数据存储效率、读写速度、文件大小、人眼可读性、跨平台兼容性 等方面。 下面总结了
.npy
,.npz
,.txt
三种常用格式的特点和适用场景:文件格式 特点 优点 缺点 适用场景 .npy
NumPy 专用二进制格式 读写速度快,效率高,存储信息完整 (数据、形状、数据类型) 不适合人眼阅读,跨平台性稍差 (主要用于 Python + NumPy 环境) NumPy 数组的持久化存储,需要快速加载和处理 NumPy 数组数据,例如中间计算结果、模型参数等 .npz
NumPy 专用压缩归档二进制格式 节省存储空间,可以 一次性保存和加载多个数组,读写速度较快 不适合人眼阅读,跨平台性稍差 (主要用于 Python + NumPy 环境),压缩和解压缩需要一定时间 需要保存多个 NumPy 数组,并且希望节省存储空间,例如模型训练数据、复杂数据集等 .txt
通用文本格式 (例如 CSV, TSV) 人眼可读性好,跨平台兼容性好,方便与其他程序或工具交换数据 文件通常较大,读写速度较慢,精度可能损失 (例如浮点数精度),NumPy 数组信息 (形状、数据类型) 需要额外处理 需要人眼查看或编辑数据,需要与其他非 Python 程序或工具交换数据,数据量不是特别大,对读写速度要求不高,例如小规模数据集、配置文件等 选择建议:
- 追求速度和效率, 主要在 Python + NumPy 环境中使用,保存和加载 NumPy 数组,优先选择
.npy
或.npz
格式。 如果需要保存多个数组并节省空间,选择.npz
格式。 - 需要人眼查看或编辑数据, 或者需要 与其他程序或工具交换数据, 选择
.txt
格式 (例如 CSV)。 但需要注意文本文件读写速度较慢,文件较大,可能损失精度,NumPy 数组信息需要额外处理。
- 追求速度和效率, 主要在 Python + NumPy 环境中使用,保存和加载 NumPy 数组,优先选择
-
案例应用: 保存和加载处理后的传感器数据
我们继续使用上一篇文章的 传感器数据异常值检测与处理 案例,演示如何将 清理后的传感器数据 保存到文件,并在需要时 加载回来,进行后续分析。
import numpy as np from PIL import Image # 仅用于读取图像,与数据保存加载无关 # ... (省略传感器数据模拟和异常值检测与处理代码,与上一篇文章案例相同,得到 sensor_data_cleaned 数组) ... # 假设我们已经得到了清理后的传感器数据 sensor_data_cleaned (异常值已替换为 NaN) # 1. 保存清理后的传感器数据到 .npy 文件 file_path_cleaned_npy = "sensor_data_cleaned.npy" np.save(file_path_cleaned_npy, sensor_data_cleaned) # 保存清理后的数据到 .npy 文件 print(f"\n清理后的传感器数据已保存到 .npy 文件: {file_path_cleaned_npy}") # 2. 保存清理后的传感器数据到 .csv 文件 file_path_cleaned_csv = "sensor_data_cleaned.csv" np.savetxt(file_path_cleaned_csv, sensor_data_cleaned, delimiter=',', header="cleaned_sensor_value", comments="# ") # 保存到 CSV 文件,逗号分隔,添加 header print(f"\n清理后的传感器数据已保存到 .csv 文件: {file_path_cleaned_csv}") # ... (假设程序关闭,稍后需要重新加载数据进行分析) ... # 3. 从 .npy 文件加载清理后的传感器数据 loaded_sensor_data_npy = np.load(file_path_cleaned_npy) # 从 .npy 文件加载数据 print("\n从 .npy 文件加载的清理后传感器数据:\n", loaded_sensor_data_npy) print("加载数据的数据类型:", loaded_sensor_data_npy.dtype) # 数据类型会被完整保留 # 4. 从 .csv 文件加载清理后的传感器数据 loaded_sensor_data_csv = np.loadtxt(file_path_cleaned_csv, delimiter=',', dtype=np.float64, skiprows=1) # 从 CSV 文件加载数据,逗号分隔,指定数据类型,跳过 header print("\n从 .csv 文件加载的清理后传感器数据:\n", loaded_sensor_data_csv) print("加载数据的数据类型:", loaded_sensor_data_csv.dtype) # 数据类型为 float64 (已指定) # 5. 对加载的数据进行进一步分析 (例如,计算平均值,与之前计算的平均值进行比较) loaded_valid_data_mean_npy = np.mean(loaded_sensor_data_npy) # 计算加载数据的平均值 print("\n从 .npy 加载的数据的平均值:\n", loaded_valid_data_mean_npy) # 应该与之前计算的 valid_data_mean 值 लगभग相同 loaded_valid_data_mean_csv = np.mean(loaded_sensor_data_csv) # 计算从 CSV 加载数据的平均值 print("\n从 .csv 加载的数据的平均值:\n", loaded_valid_data_mean_csv) # 应该与之前计算的 valid_data_mean 值 लगभग相同
代码解释:
- 保存清理后的数据: 使用
np.save()
将清理后的传感器数据sensor_data_cleaned
保存到.npy
文件,使用np.savetxt()
保存到.csv
文件。 - 加载数据: 使用
np.load()
从.npy
文件加载数据,使用np.loadtxt()
从.csv
文件加载数据。 注意加载.csv
文件时需要 指定分隔符delimiter=','
, 数据类型dtype=np.float64
,并 跳过 header 行skiprows=1
。 - 数据验证: 计算加载数据的平均值,并与之前计算的平均值进行比较,验证数据是否被正确保存和加载。 由于浮点数精度问题,两次计算的平均值可能 не完全一致,但应该非常接近。
这个案例演示了 NumPy 数组文件 I/O 的基本工作流程: 保存数据 -> 关闭程序 -> 加载数据 -> 继续分析。 通过 NumPy 的文件 I/O 功能,我们可以轻松地 持久化数据分析的中间结果和最终成果, 构建更完整、更高效的数据分析流程。
- 保存清理后的数据: 使用
费曼回顾 (知识巩固):
现在,请你用自己的话,总结一下今天我们学习的 NumPy 数组文件 I/O 的知识,包括:
- NumPy 提供了哪些常用的函数来保存 NumPy 数组到文件?
.npy
,.npz
,.txt
三种文件格式分别有什么特点和适用场景? np.save()
和np.savez()
函数有什么区别? 什么情况下使用np.save()
,什么情况下使用np.savez()
?np.savetxt()
函数有什么作用? 如何使用np.savetxt()
保存 NumPy 数组为 CSV 格式的文本文件?fmt
,delimiter
,header
,footer
等参数有什么作用?- NumPy 提供了哪些常用的函数来加载 NumPy 数组从文件?
np.load()
和np.loadtxt()
函数分别适用于加载哪些文件格式? 如何加载.npy
,.npz
,.txt
,.csv
文件? - 在传感器数据处理案例中,我们是如何运用 NumPy 的文件 I/O 功能来保存和加载数据的?
像给你的同事讲解一样,用清晰简洁的语言解释这些概念,并结合传感器数据处理案例,帮助他们理解 NumPy 文件 I/O 的实用价值。
课后思考 (拓展延伸):
- 尝试修改传感器数据文件 I/O 案例的代码,例如:
- 尝试使用不同的格式保存传感器数据,例如
.npz
格式 (保存多个数组,例如原始数据和清理后的数据)? 或者 TSV 格式 (制表符分隔的文本文件)? - 尝试加载更大规模的传感器数据文件 (例如,包含数百万行数据的 CSV 文件),看看 NumPy 文件 I/O 的性能如何?
- 尝试使用
np.genfromtxt()
函数加载更复杂的文本文件 (例如,包含缺失值、不同数据类型混合的文本文件)?
- 尝试使用不同的格式保存传感器数据,例如
- 思考一下,除了传感器数据处理,NumPy 数组文件 I/O 还可以应用在哪些数据分析和科学计算场景中? 例如,机器学习模型参数保存和加载、图像数据批量处理、音频信号数据存储等等。 你有什么新的应用场景想法吗?
- 尝试查阅 NumPy 官方文档或其他 NumPy 教程,了解更多关于 NumPy 文件 I/O 的高级特性,例如:
- 内存映射 (memory mapping): 直接将文件内容 映射到内存,无需完全加载到内存中,可以 高效处理超大型文件 (超出内存大小的文件)。 使用
np.memmap()
函数创建内存映射数组。 - 文件压缩:
np.savez()
函数的compression
参数,可以指定不同的压缩算法,进一步减小.npz
文件大小。 - 与其他库的集成: NumPy 文件 I/O 与其他数据分析库 (例如 Pandas) 的集成应用,例如使用 Pandas 读取 CSV 文件,转换为 NumPy 数组进行处理,再将结果保存为 CSV 文件。
- 内存映射 (memory mapping): 直接将文件内容 映射到内存,无需完全加载到内存中,可以 高效处理超大型文件 (超出内存大小的文件)。 使用
恭喜你!完成了 NumPy 费曼学习法的第五篇文章学习! 你已经掌握了 NumPy 数组的 “文件魔法”,可以开始构建更完整、更高效的数据分析工作流程了! 下一篇文章,我们将探索 NumPy 在 线性代数 方面的强大能力,学习如何使用 NumPy 进行 矩阵运算、线性方程组求解 等,为后续学习机器学习和更高级的科学计算打下基础! 敬请期待!