PyTorch 数据预处理
数据预处理
为了能用深度学习来解决现实世界的问题,我们经常从预处理原始数据开始, 而不是从那些准备好的张量格式数据开始。 在 Python 中常用的数据分析工具中,我们通常使用 pandas 软件包。
Pandas 是什么?
Pandas 是一个Python编程语言的开源数据分析和数据处理库。它提供了高效、灵活的数据结构,使用户能够轻松地操作和分析结构化数据。Pandas 主要关注于两种核心数据结构:Series 和 DataFrame。
- Series:
Series是一维标签化的数组,类似于带有标签索引的列表。每个元素可以是任何数据类型。Series可以用于处理时间序列数据、数值数据等。 - DataFrame:
DataFrame是二维表格数据结构,类似于电子表格或SQL数据库表。它由多个行和列组成,每列可以包含不同的数据类型。DataFrame用于处理结构化的表格型数据,可以进行各种数据操 作和分析。
Pandas 提供了丰富的数据操作和处理功能,包括:
- 数据加载和存储:从各种格式(如CSV、Excel、SQL数据库等)中加载数据,以及将数据保存为不同格式。
- 数据清洗:处理缺失值、重复值和异常值。
- 数据选择和索引:通过标签或位置进行数据选择和切片。
- 数据转换:对数据进行重塑、合并、连接和分组等操作。
- 数据分析:计算统计指标、绘制图表、执行聚合操作等。
- 时间序列分析:支持处理日期和时间数据,进行时间序列分析。
- 数据可视化:使用 Matplotlib 或其他库绘制各种图表。
Pandas 是数据科学和数据分析领域的重要工具,它提供了强大的数据操作和处理能力,使用户能够更轻松地处理和分析大规模数据。
Pandas 的常用方法
Pandas 数据切片(索引)
iloc 是 Pandas 中的一个方法,用于根据整数位置对 DataFrame 或 Series 进行索引和切片。它允许你通过行和列的整数索引来选择数据。
对于 DataFrame,iloc 方法可以接受两个整数索引或切片来指定需要选择的行和列。例如,df.iloc[1:3, 0:2] 会选择第 1 到第 2 行以及第 0 到第 1 列的数据。
对于 Series,iloc 方法只需要一个整数索引或切片,用于选择 Series 中的元素。
以下是一些示例 说明 iloc 的用法:
import pandas as pd
# 创建示例 DataFrame
data = {'A': [1, 2, 3, 4],
'B': [5, 6, 7, 8]}
df = pd.DataFrame(data)
# 使用 iloc 进行索引和切片
subset = df.iloc[1:3, 0:2] # 选择第 1 到第 2 行和第 0 到第 1 列的数据
column_data = df['A'].iloc[0:2] # 选择 'A' 列中的第 0 到第 1 个元素
print("Subset of DataFrame:")
print(subset)
print("Selected Data from 'A' Column:")
print(column_data)
在这个示例中,我们展示了如何在 DataFrame 和 Series 上使用 iloc 进行索引和切片操作。
读取数据集
下面将模拟的数据集按行写入 CSV 文件中
import os
os.makedirs(os.path.join('.', 'data'), exist_ok=True)
data_file = os.path.join('.', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n') # 每行表示一个数据样本
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
上面的函数将会创建一个简单的数据集,要从创建的 CSV 文件中加载原始数据集,我们导入 pandas 包并调用 read_csv 函数。 该数据集有四行三列。其中每行描述了房间数量(“NumRooms”)、巷子类型(“Alley”)和房屋价格(“Price”)。
# 如果没有安装 pandas,只需取消对以下行的注释来安装 pandas
# !pip install pandas
import pandas as pd
data = pd.read_csv(data_file)
print(data)
NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000
处理缺失的数据
可以看到上面包含了部分 “NaN” 项,这个 “NaN”项代表缺失值。
在 Pandas 中,处理缺失数据是数据清洗的一个重要步骤。缺失数据可能会影响分析和模型的准确性,因此需要采取适当的方法来处理。以下是一些处理缺失数据的常见方法:
- 检测缺失值:
使用
isnull()或notnull()函数来检测 DataFrame 或 Series 中的缺失值。这些函数将返回布尔值,指示每个元素是否为缺失值。
import pandas as pd
data = {'A': [1, 2, None, 4],
'B': [5, None, 7, 8]}
df = pd.DataFrame(data)
# 检测缺失值
print(df.isnull())
A B 0 False False 1 False True 2 True False 3 False False
- 删除缺失值:
使用
dropna()函数删除包含缺失值的行或列。可以通过设置axis参数来指定是删除行(axis=0)还是列(axis=1)。
# 删除包含缺失值的行
cleaned_df = df.dropna()
print("============df.dropna()============")
print(cleaned_df)
# 删除包含缺失值的列
cleaned_df = df.dropna(axis=1)
print("============df.dropna(axis=1)============")
print(cleaned_df)
============df.dropna()============ A B 0 1.0 5.0 3 4.0 8.0 ============df.dropna(axis=1)============ Empty DataFrame Columns: [] Index: [0, 1, 2, 3]
- 填充缺失值:
使用
fillna()函数填充缺失值。你可以提供一个常数值、平均值、中位数等来填充缺失值。
# 使用常数填充缺失值
filled_df = df.fillna(0)
print(filled_df)
# 使用列的平均值填充缺失值
filled_df = df.fillna(df.mean())
print(filled_df)
A B 0 1.0 5.0 1 2.0 0.0 2 0.0 7.0 3 4.0 8.0 A B 0 1.000000 5.000000 1 2.000000 6.666667 2 2.333333 7.000000 3 4.000000 8.000000
- 插值填充:
使用
interpolate()函数进行插值填充,以使用相邻值推断缺失值。这在处理时间序列数据时特别有用。
# 使用插值填充
interpolated_df = df.interpolate()
print(interpolated_df)
A B 0 1.0 5.0 1 2.0 6.0 2 3.0 7.0 3 4.0 8.0
- 设定缺失值标记:
在读取数据时,可以使用
na_values参数指定输入文件中表示缺失值的特定标记。例如标记上面创建的数据集中NA、NaN和-1为缺失值:
# 读取 CSV 文件时指定缺失值标记
df = pd.read_csv('data/house_tiny.csv', na_values=['NA', 'NaN', '-1'])
print(df)
NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000
这些方法可以根据情况选择,根据数据类型、分析任务以及数据缺失的程度来决定。处理缺失数据需要根据具体情况进行调整,以确保清洗后的数据适合进行后续分析和建模。
切割数据为输入输出
现在我想把输入的数据切割成输入和输出,例如下面的
NumRooms,Alley,Price
NA,Pave,127500
2,NA,106000
4,NA,178100
NA,NA,140000
前面的两行是输入,最后一行是输出,并且处理一下上面的缺失值
Pandas 会自动读取第一行作为列名
df_example = pd.read_csv('Pandas_example_read.csv')
# 等同于:
df_example = pd.read_csv('Pandas_example_read.csv', header=0)
如果不想要第一行作为列名,可以设置 header=None
df_example = pd.read_csv('Pandas_example_read.csv', header=None)
下面是填充缺失值的方法
# 读取数据文件
data = pd.read_csv('data/house_tiny.csv', na_values=['NA'])
print("Original Data:")
print(data)
# 使用每列的均值来填充缺失值
# 2.0 版本,API 有一些细微的变化。
# 调用 inputs.mean() 的时候会出现字符串和数字不能拼接的错误是因为 NaN 是数字,‘Pave’ 是字符串。
# 解决方案:添加额外参数 inputs.mean(numeric_only=True),从而忽略对于字符串的处理。
data_filled = data.fillna(data.mean(numeric_only=True))
print("Missing Values Filled:")
print(data_filled)
# 划分输入和输出
inputs = data_filled.iloc[:-1, :-1] # 前三行是输入
outputs = data_filled.iloc[-1:, -1] # 最后一行是输出
print("Inputs with Missing Values Filled:")
print(inputs)
print("Outputs:")
print(outputs)
Original Data: NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000 Missing Values Filled: NumRooms Alley Price 0 3.0 Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 3.0 NaN 140000 Inputs with Missing Values Filled: NumRooms Alley 0 3.0 Pave 1 2.0 NaN 2 4.0 NaN Outputs: 3 140000 Name: Price, dtype: int64
转换为张量格式
如果你想将 Pandas DataFrame 转换为 PyTorch 张量(Tensor)格式,你可以使用 torch.tensor() 函数将 DataFrame 的值转换为张量。在转换过程中,确保数据类型一致,以便能够有效地在 PyTorch 中进行计算。以下是一个将输入和输出数据转换为张量格式的示例:
import torch
# 选择只包含数值类型的列
numeric_columns = data_filled.select_dtypes(include=[float, int])
# 划分输入和输出
inputs = numeric_columns.iloc[:-1, :-1] # 前三行是输入
outputs = numeric_columns.iloc[-1:, -1] # 最后一行是输出
# 转换为 PyTorch 张量
inputs_tensor = torch.tensor(inputs.values, dtype=torch.float32)
outputs_tensor = torch.tensor(outputs.values, dtype=torch.float32)
print("Inputs as Tensors:")
print(inputs_tensor)
print("Outputs as Tensors:")
print(outputs_tensor)
Inputs as Tensors: tensor([[3.], [2.], [4.]]) Outputs as Tensors: tensor([140000.])