介绍
在本实验中,你将学习如何使用 numpy.genfromtxt 函数从文本文件中导入表格数据。NumPy (Numerical Python) 是 Python 中科学计算的基础库,它提供了强大的数据结构和函数来处理数值数据。其核心数据结构是NumPy 数组——一种快速、内存高效的方式来存储和操作大型数据集。
numpy.genfromtxt 函数是 Python 数据分析的基石,它允许你读取结构化数据并将其转换为 NumPy 数组。我们将从基础导入开始,并逐步添加选项来处理常见的实际场景,例如标题行、不同的列分隔符、缺失值以及选择特定的数据列。所有操作都将在 WebIDE 中通过编写和执行 Python 脚本来完成。
使用 genfromtxt 进行基本数据加载
首先,让我们熟悉一下环境。在左侧的文件浏览器中,你将看到两个文件:main.py 和 my_data.csv。我们将在 main.py 中编写 Python 代码来加载 my_data.csv 中的数据。
numpy.genfromtxt 函数最基本的使用需要一个参数:数据源的路径。让我们尝试使用默认设置加载数据文件。
打开 main.py 文件并在其中添加以下代码:
import numpy as np ## 这会导入 NumPy 并为其指定别名 'np' 以方便使用
## 从 CSV 文件加载数据
## 相对路径会导致验证失败,请在实验中使用绝对路径
data = np.genfromtxt('/home/labex/project/my_data.csv')
## 打印结果数组
print(data)
现在,保存文件并从 IDE 底部的终端运行它。
python main.py
你将看到以下输出:
[nan nan nan nan]
这个输出可能会让你感到意外。结果是一个包含 nan (Not a Number) 值的数组。NaN 是一个特殊的浮点数值,表示未定义或不可表示的数值结果——这是 NumPy 表示无法正确转换为数字的值的方式。之所以出现这种情况,是因为 genfromtxt 默认会尝试按空格分割行,并将所有内容解释为浮点数。我们的 my_data.csv 文件使用逗号作为分隔符,并且包含一个非数字的标题行,这导致默认导入失败。在下一步中,我们将解决这个问题。
指定分隔符和跳过标题
为了正确解析我们的 my_data.csv 文件,我们需要告知 genfromtxt 两件事:
- 数据由逗号分隔。
- 第一行是标题行,应该被忽略。
我们可以使用 delimiter 和 skip_header 参数来实现这一点。
delimiter=',': 这告诉函数使用逗号来分隔值。skip_header=1: 这告诉函数忽略文件的第一行。
使用更新后的代码修改你的 main.py 文件:
import numpy as np ## 导入 NumPy 库
## 加载数据,指定分隔符并跳过标题行
data = np.genfromtxt('/home/labex/project/my_data.csv', delimiter=',', skip_header=1)
## 打印结果数组
print(data)
保存文件并在终端中再次运行它:
python main.py
输出现在看起来好多了:
[[ 1. 22.5 45. ]
[ 2. 23.1 48. ]
[ 3. nan 46. ]
[ 4. 23.5 52. ]]
如你所见,数据现在被结构化为一个二维数组 (two-dimensional array)。你可以将其想象成一个带有行和列的表格或电子表格——我们的数组有 4 行(对应每个传感器读数)和 3 列(传感器 ID、温度、湿度)。数字被正确解析为浮点数 (floats),即可以表示 22.5 这样小数的数值。然而,请注意第三行中的 nan。这是因为我们的源文件使用文本 NA 来表示缺失的温度读数,而 genfromtxt 无法将其识别为数字。我们将在下一步中解决这个问题。
处理缺失值
真实世界的数据集通常是不完整的。genfromtxt 提供了一种使用 missing_values 和 filling_values 参数来干净地处理这种情况的方法。
missing_values: 应被解释为缺失数据的字符串或字符串列表。filling_values: 用于替换任何缺失条目的值。
在我们的数据中,缺失值由 NA 表示。让我们告诉 genfromtxt 识别 NA 为缺失值,并用 -99 替换它,以便于识别。
按如下方式更新你的 main.py 文件:
import numpy as np ## 导入 NumPy 库
## 处理缺失值
data = np.genfromtxt('/home/labex/project/my_data.csv', delimiter=',', skip_header=1,
missing_values='NA', filling_values=-99)
## 打印结果数组
print(data)
保存文件并执行它:
python main.py
输出现在显示了一个完整的数值数组,缺失值已被替换:
[[ 1. 22.5 45. ]
[ 2. 23.1 48. ]
[ 3. -99. 46. ]
[ 4. 23.5 52. ]]
现在我们的数据是干净且完全数值化的,可以进行计算了。
选择列和设置数据类型
有时,你只需要一部分数据。usecols 参数允许你指定要导入的列。它接受一个元组 (tuple),即一个不可变的数值序列,例如 (1, 2),其中包含列的索引(从 0 开始)。例如,usecols=(1, 2) 表示“仅导入第 1 列和第 2 列”。
此外,你可以使用 dtype 参数为所有导入的数据强制指定一种特定的数据类型 (data type)。在编程中,数据类型决定了值的存储方式以及可以对其执行的操作。例如,dtype=int 会将所有值转换为整数(whole numbers),dtype=float 确保它们保持为浮点数(decimals),而 dtype=str 则将它们视为文本。请注意,dtype=int 会截断任何小数部分(22.5 会变成 22)。
让我们修改脚本,仅导入 Temperature(第 1 列)和 Humidity(第 2 列),并确保它们被视为浮点数。
最后一次更新 main.py:
import numpy as np ## 导入 NumPy 库
## 选择特定列并设置数据类型
data = np.genfromtxt('/home/labex/project/my_data.csv', delimiter=',', skip_header=1,
missing_values='NA', filling_values=0,
usecols=(1, 2), dtype=float)
## 打印结果数组
print(data)
注意:在此示例中,我们将
filling_values改为了0。
保存文件并在终端中运行它:
python main.py
最终输出将是一个只包含温度和湿度数据的二维数组:
[[22.5 45. ]
[23.1 48. ]
[ 0. 46. ]
[23.5 52. ]]
你已成功导入并清理了一个数据集,只选择了相关的列,并在此过程中处理了所有数据不一致的问题。
总结
在本实验中,你学会了如何有效地使用 numpy.genfromtxt 将文本文件中的数据导入 NumPy 数组。你练习使用了几个关键参数来应对真实世界的数据挑战:
delimiter: 用于指定列的分隔方式。skip_header: 用于忽略数据文件中的标题行。missing_values: 用于识别代表缺失数据的自定义字符串。filling_values: 用于将缺失数据替换为特定值。usecols: 用于仅导入特定列的子集。dtype: 用于控制结果数组的数据类型。
掌握 genfromtxt 是任何使用 Python 和 NumPy 的数据科学家或工程师的一项基本技能。



