【李沐深度学习笔记】数据预处理实现

课程地址和说明

数据预处理实现p3
本系列文章是我学习李沐老师深度学习系列课程的学习笔记,可能会对李沐老师上课没讲到的进行补充。

数据预处理

Python文件操作

OS标准库

Python的OS标准库是一个操作系统接口模块,提供一些方便使用操作系统相关功能的函数。这里只提及李沐老师示例代码中的各种函数的用法,至于该库的其他内容请参考网络。

os.makedir方法

os.makedir是python中常用的一个函数,用于创建一个文件夹或目录,以便存储文件和数据。可以一次性创建多层文件夹,还可以指定权限和路径。在使用os.makedir时,我们需要注意路径和权限的问题。如果不设置路径,默认在当前工作目录下创建文件夹;如果不指定权限,默认权限为os.umask(0) & 0o777,即最高权限。

os.makedir的基本用法

os.makedir(path, mode=0o777, *, dir_fd=None)
  • path:文件夹路径,可以是相对路径或绝对路径。如果存在多层文件夹,需要一次性创建,需要使用os.makedirs()。
  • mode:权限,指定创建的目录权限,默认为0o777,即最高权限。
  • dir_fd:文件描述符。

os.makedirs 方法

os.makedirs() 方法用于递归创建目录。

os.makedirs 的基本用法

os.makedirs(path, mode=0o777)
  • path – 需要递归创建的目录,可以是相对或者绝对路径

  • mode – 权限模式。

  • exist_ok – 当其为True时,如果某个要创建的目录已经存在,也不报错,为False则相反。

os.path.join的用法

os.path.join(path1, path2, ...)

路径合并函数,这个函数会把所有参数合并成一个路径字符串,其中除了最后一个参数之外,其它所有参数都会自动在字符串末尾添加目录分隔符(斜杠或者反斜杠),linux系统下默认添加斜杠,windows下默认添加一个反斜杠。

with open

它用来打开本地文件的,他会在使用完毕后,自动关闭文件,相对open()省去了写close()的麻烦

用法

with open(file="你要打开的路径名(或保存内容的地址)",mode="r/w/a",encoding="utf-8") as f:
    data=f.read/write()
    print(data)

如果没有指定的路径,会自动新建文件,无需先去新建。
关于mode的全部模式:

  • r: 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
  • rb: 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
  • r+: 打开一个文件用于读写。文件指针将会放在文件的开头。
  • rb+:以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
  • w: 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • wb: 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • w+: 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • wb+:以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
  • a: 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
  • ab: 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
  • a+: 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
  • ab+:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

file对象的方法

  • file.read([size]) 将文件数据作为字符串返回,可选参数size控制读取的字节数
  • file.readlines([size]) 返回文件中行内容的列表,size参数可选
  • file.write(str) 将字符串写入文件
  • file.writelines(strings) 将字符串序列写入文件
  • file.close() 关闭文件
  • file.closed 表示文件已经被关闭,否则为False
  • file.mode Access文件打开时使用的访问模式
  • file.encoding 文件所使用的编码
  • file.name 文件名
  • file.newlines 未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表
  • file.softspace 为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般程序员用不着,由程序内部使用

CSV文件

逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。

创建CSV文件

# 这是Windows系统下,Linux系统需要注意路径标识方法和Windows系统不同,具体请网络搜索
import os
#创建根目录下data文件夹,路径为./data
# exist_ok当其为True时,如果某个要创建的目录已经存在,也不报错,为False则相反
os.makedirs(os.path.join( '.', 'data' ), exist_ok=True)
#在./data路径下创建文件house_tiny.csv
data_file = os.path.join( '.', 'data', 'house_tiny.csv')
# 使用utf-8编码来方便写入中文字符串
with open (data_file, 'w', encoding="utf-8") as f:
    f.write( '房间数目,所在街道,价格\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' )

【注】NA的意思是非数字,未知

读取CSV文件

一般使用Pandas库读取CSV文件

import pandas as pd

# 读取CSV文件
data = pd.read_csv(data_file)
print(data)

运行结果:
房间数目 所在街道 价格
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000

【注】NaN也是非数字,未知,Not-a-Number

处理缺失的数据

为了处理缺失的数据,典型的方法包括插值和删除这里,我们将考虑插值。(下文中的data变量都将使用上文读取的csv文件对应的data变量

对数值类型的缺失值进行插值

inputs = data.iloc[:,0:2] # 从所有的行中取第1列到第2列放入inputs中(0:2)左闭右开
outputs = data.iloc[:,2] # 从所有的行中取下标为2(第三列)的列放入outputs中
print("插值前:")
print(inputs)
# 用inputs中的每一列均值去插值到NaN中(字符串没有均值,所以不填,还是原来的)
# inputs = inputs.fillna(inputs.mean()) ,如果直接这样写,jupyter notebook会报警告
# 因为我们不能直接对字符串求均值,我们只能对数值求均值
# 虽然警告也能正常运行,但是为了严谨,这里我们还是只允许数值类型的数据求均值
inputs = inputs.fillna(inputs.mean(numeric_only = True))
print("-------------")
print("插值后:")
print(inputs)

运行结果:

插值前:
   房间数目 所在街道
0 NaN Pave
1 2.0 NaN
2 4.0 NaN
3 NaN NaN

-------------

插值后:
   房间数目 所在街道
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN

对非数值类型的缺失值进行插值

对于inputs中的类别值或离散值,我们将“NaN”视为一个类别。

print("分类前:")
print(inputs)
inputs = pd.get_dummies(inputs,dummy_na=True) # 将出现缺失值的数据分为两类
print("分类后:")
print(inputs)

运行结果:
分类前:
房间数目 所在街道
0   3.0      Pave
1   2.0      NaN
2   4.0      NaN
3   3.0      NaN
分类后:
   房间数目 所在街道_Pave 所在街道_nan
0   3.0            1                        0
1   2.0             0                        1
2   4.0            0                         1
3   3.0            0                         1

【提问】简述一下Python的Pandas库中的get_dummies的功能。
【chatGPT回答】在Python的Pandas库中,get_dummies()函数是用于进行数据编码(One-Hot编码)的方法。它将分类变量转换成哑变量(dummy variables),以便更好地在机器学习模型中使用。
分类变量是指具有离散取值的变量,如性别(男、女)、颜色(红、绿、蓝)等。机器学习算法通常无法处理这些分类变量,因为它们期望输入为数字。get_dummies()函数的目的就是将这些分类变量转换成数字形式,以便机器学习算法可以更好地理解和使用它们。
get_dummies()函数的工作方式很简单:对于输入的分类变量列,它会创建多个新的二进制(0或1)列,每个值对应一个类别。对于原始数据中的每个分类变量,函数会为每个类别创建一个新的列,并在对应的位置上设置为1,其他列则设置为0。
例如,假设有一个名为color的分类变量列,包含三种颜色:红、绿和蓝。使用get_dummies()函数对该列进行编码后,将生成三个新的列:color_红、color_绿和color_蓝。对于每一行数据,它们中的一个列会设置为1,表示该行数据属于对应的颜色,而其他列则设置为0。
这种编码转换可以帮助机器学习算法更好地处理分类变量,因为现在数据以数字表示,并且每个类别都有一个对应的特征列。
总而言之,get_dummies()函数可以将分类变量转换成多个二进制特征列,以便在数据的分析和建模过程中使用。

上述情况的所在街道总共就两种数据,一种是NaN缺失值,另一种是Pave,所以可以分成两个类别(即所在街道_Pave和所在街道_nan)进行输出,其中1代表True,0代表False。

转换为张量格式

现在inputs和 outputs 中的所有条目都是数值类型,它们可以转换为张量格式。

import torch
# 标记一下刚才的变量的用途
# inputs = data.iloc[:,0:2] # 从所有的行中取第1列到第2列放入inputs中(0:2)左闭右开
# outputs = data.iloc[:,2] # 从所有的行中取下标为2(第三列)的列放入outputs中
x,y = torch.tensor(inputs.values), torch.tensor(outputs.values)
print(x)
print(y)

运行结果:
tensor([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=torch.float64)
tensor([127500, 106000, 178100, 140000])
【注】x的元素数据类型是float64,传统的Python默认浮点数是64位的,但是64位浮点数计算较慢,后面会用32位浮点数。

你可能感兴趣的:(李沐深度学习,深度学习,笔记,人工智能)