1. 包/模块():
- 在 中,包是一个包含多个模块的目录,通常有一个 文件来标识它是一个包。
- 模块是一个包含 代码的文件,通常以结尾。
2.
- 使用 import 语句来导入整个模块或模块中的特定部分。
3.
在中,是一个标准库模块,用于编写用户友好的命令行接口。它使得从命令行解析参数变得简单明了,并且能够生成帮助和用法消息。以下是一个简单的示例,展示了如何使用模块来定义命令行参数并解析它们:
import argparse
# 创建一个ArgumentParser对象
parser = argparse.ArgumentParser(description='一个简单的命令行程序示例')
# 添加命令行参数
parser.add_argument('--input', type=str, help='输入文件的路径')
parser.add_argument('--output', type=str, help='输出文件的路径')
parser.add_argument('--verbose', action='store_true', help='增加输出信息')
# 解析命令行参数
args = parser.parse_args()
# 使用解析后的参数
if args.input:
print(f'输入文件路径: {args.input}')
if args.output:
print(f'输出文件路径: {args.output}')
if args.verbose:
print('Verbose mode is on.')
# 示例中的其他逻辑...
4.
- 在 模块中, 通常是一个由 方法返回的命名空间对象,该对象包含了从命令行解析出来的所有参数值。当你使用 添加参数定义后, 方法会解析命令行中提供的参数,并将它们作为属性存储在返回的
5. 方法
在中,字符串的方法是一个强大的工具,用于将变量或表达式的值嵌入到字符串中。
基本用法
- 使用大括号作为占位符,然后在方法中提供对应的值或表达式。
name = "Alice"
age = 30
formatted_string = "My name is {} and I am {} years old.".format(name, age)
print(formatted_string) # 输出: My name is Alice and I am 30 years old.
格式化选项
- 字段名:可以为占位符指定名称,以便在方法中按名称提供值。
- 转换标志:可以指定转换类型(如为字符串,为表示等)。
- 格式说明符:可以指定宽度、精度、填充和对齐方式等。
"{:<10}".format("left") # 输出: 'left '(左对齐,总共10个字符宽度)
"{:^10}".format("center") # 输出: ' center '(居中对齐)
"{:>10}".format("right") # 输出: ' right'(右对齐)
"{:0>10}".format(123) # 输出: '0000000123'(右对齐,用0填充)
"{:.2f}".format(3.1415926) # 输出: '3.14'(浮点数,保留两位小数)
命名参数
- 可以为占位符指定名称,并在方法中通过名称提供值。
"{name} is {age} years old.".format(name="Alice", age=30)
# 输出: Alice is 30 years old.
格式化字典
- 可以直接使用字典的键来格式化字符串。
person = {"name": "Bob", "age": 25}
print("{name} is {age} years old.".format(**person))
# 输出: Bob is 25 years old.
#从Python 3.6开始,引入了f-string(格式化字符串字面量),它提供了一种更简洁、更易读的字符串格式化方式。
name = "Charlie"
age = 40
formatted_string = f"My name is {name} and I am {age} years old."
print(formatted_string) # 输出: My name is Charlie and I am 40 years old.
6. 常用库函数
6.1
- 在深度学习项目中,您可能会使用 模块来读取配置文件、处理模型和数据文件的路径、创建和删除目录等。
current_dir = os.getcwd() # 获取当前工作目录
files_in_dir = os.listdir(current_dir) # 列出当前目录下的文件
6.2
- 是深度学习库的简称。是一个开源的机器学习库,用于快速实现深度学习模型。
- 它提供了大量的工具和函数,用于构建和训练神经网络,包括自动微分、加速、优化算法等。 在深度学习项目中,您会使用 来定义网络结构、初始化参数、进行前向传播、计算损失、反向传播和更新参数等。
# 创建一个张量
x = torch.tensor([1.0, 2.0, 3.0])
# 对张量进行操作
y = torch.exp(x)
6.3
- numpy 是Python中用于科学计算的基础库,它提供了大量的数学函数和工具来处理大型多维数组和矩阵。 numpy的数组(ndarray)是固定大小的同类型元素的多维容器,并提供了高效的运算和广播功能。
- 在深度学习项目中,尽管PyTorch提供了自己的张量(tensor)类,但 numpy 仍然经常用于数据处理、特征工程和结果可视化等任务。
- 由于PyTorch的张量(tensor)和 numpy 的数组(ndarray)可以相互转换,因此这两个库经常一起使用。
7.
7.1
- 是 标准库 模块中的一个环境变量字典。它表示当前进程的环境变量,可以用来读取、设置或删除环境变量的值。这个字典的键和值都是字符串类型。
import os
# 读取环境变量
path = os.environ.get('PATH')
print(f'PATH environment variable: {path}')
# 设置环境变量
os.environ['MY_VARIABLE'] = 'some_value'
# 删除环境变量(注意:这只会影响当前进程及其子进程的环境)
del os.environ['MY_VARIABLE']
8.
8.1
- 是一个类,用于指定张量()应该分配在哪个设备上(或其他设备)。当你有多个并且想要指定使用哪一个时,你会用到类似你给出的代码片段来创建一个
# 假设你有一个PyTorch模型 model 和一些数据 input_data
# 将模型移到指定的设备上
model.to(device)
# 将数据移到指定的设备上
input_data = input_data.to(device)
# 现在,你可以在这个设备上进行前向传播等操作
output = model(input_data)
8.2
- 在中,是一个上下文管理器,用于在评估模型或进行不涉及梯度的计算时禁用梯度计算。当你在训练神经网络时,你通常想要计算梯度以便更新模型的权重,但在评估模型或进行推理时,你不需要(也不希望)计算梯度,因为这会增加计算量和内存消耗。
- 使用
1.节省内存:因为不需要存储任何中间变量的梯度,所以可以减少内存使用量。
2.加速计算:没有梯度计算意味着可以更快地执行前向传播。
3.避免不必要的计算:计算梯度通常比仅进行前向传播要慢,所以禁用梯度可以加速你的代码。
- 你可以使用
import torch
# 假设有一个训练好的模型 model 和一些输入数据 inputs
model.eval() # 确保模型处于评估模式
with torch.no_grad():
outputs = model(inputs)
# 在这个上下文中,任何涉及 tensor 的操作都不会计算梯度
# 当你退出 torch.no_grad() 上下文后,你可以再次计算梯度(如果需要的话)
- 另外,如果你只是想要一个特定的tensor不计算梯度,你可以使用 tensor.detach() 或
tensor.requires_grad_(False)。但是,torch.no_grad() 更适合在一段较长的代码中禁用梯度计算。 - 需要注意的是,虽然 torch.no_grad() 禁用了梯度计算,但它不会改变tensor的 requires_grad
属性。这意味着即使你在 torch.no_grad() 上下文中创建了一个新的tensor,并且设置其
requires_grad=True,它也不会计算梯度。要真正改变tensor的 requires_grad 属性,你需要使用
tensor.requires_grad_(True) 或 tensor.requires_grad_(False)。
8.3
- 在中,函数用于返回输入张量()的上三角部分(包括对角线)。这个函数在处理矩阵运算,特别是当你只对矩阵的上三角部分感兴趣时,非常有用。
torch.triu(input, diagonal=0, out=None) → Tensor
#input (Tensor):输入张量。
#diagonal (int, 可选):指定对角线。默认值为0,表示主对角线。正值表示主对角线上方的对角线,负值表示主对角线下方的对角线。
#out (Tensor, 可选):输出张量。
#返回值是一个与输入张量形状相同的张量,但只包含上三角部分(包括指定的对角线)。其余部分被设置为0。
import torch
# 创建一个3x3的矩阵
x = torch.tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 获取上三角部分(包括主对角线)
y = torch.triu(x)
print(y)
# 输出:
# tensor([[1, 2, 3],
# [0, 5, 6],
# [0, 0, 9]])
# 获取主对角线上方的上三角部分
z = torch.triu(x, diagonal=1)
print(z)
# 输出:
# tensor([[0, 2, 3],
# [0, 0, 6],
# [0, 0, 0]])
8.4
- 在中,是一个用于创建全为的张量()的函数。你可以指定张量的形状()、数据类型()和设备()等参数。
torch.ones(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
#*sizes (int...):定义张量形状的整数序列。
#out (Tensor, 可选):输出张量。
#dtype (torch.dtype, 可选):返回张量的数据类型。
#layout (torch.layout, 可选):返回张量的内存布局。
#device (torch.device, 可选):返回张量的设备。
#requires_grad (bool, 可选):是否需要计算梯度。
import torch
# 创建一个形状为 (3,) 的一维张量,全为1
tensor1 = torch.ones(3)
print(tensor1)
# 输出:tensor([1., 1., 1.])
# 创建一个形状为 (2, 3) 的二维张量,全为1
tensor2 = torch.ones((2, 3))
print(tensor2)
# 输出:
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
# 创建一个形状为 (2, 3) 的二维张量,全为1,数据类型为整数
tensor3 = torch.ones((2, 3), dtype=torch.int)
print(tensor3)
# 输出:
# tensor([[1, 1, 1],
# [1, 1, 1]], dtype=torch.int32)
# 创建一个形状为 (2, 3) 的二维张量,全为1,并指定需要计算梯度
tensor4 = torch.ones((2, 3), requires_grad=True)
print(tensor4)
# 输出:tensor([[1., 1., 1.],
# [1., 1., 1.]], requires_grad=True)
8.5
- 在中,是一个常用的方法,用于将一个张量()或整个模型()移动到指定的设备上,比如或。这个方法允许你轻松地在不同的设备之间转移数据和模型,以便在多个设备上进行计算。
- 可以是一个字符串(如或 ),也可以是一个 对象。如果支持并且你有一个可用的,那么 或 将指向第一个可用的。如果你有多个,并且想要指定一个特定的,你可以使用 等,或者等。
- 以下是一些使用
import torch
#示例1:移动张量到GPU
# 假设我们有一个张量
tensor = torch.tensor([1.0, 2.0, 3.0])
# 检查是否有可用的GPU
if torch.cuda.is_available():
device = torch.device('cuda') # 一个设备对象表示第一个GPU
tensor = tensor.to(device) # 将张量移动到GPU
else:
device = torch.device('cpu')
# 现在tensor在指定的设备上
import torch
import torch.nn as nn
#示例2:移动模型到GPU
# 定义一个简单的模型
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc = nn.Linear(10, 1)
def forward(self, x):
return self.fc(x)
model = SimpleModel()
# 检查是否有可用的GPU
if torch.cuda.is_available():
device = torch.device('cuda')
model = model.to(device) # 将模型移动到GPU
else:
device = torch.device('cpu')
# 现在模型在指定的设备上
#示例3:移动数据和模型到同一GPU
#在训练神经网络时,你通常希望数据和模型都在同一个GPU上,以减少数据传输的开销。你可以使用 .to(device) 来实现这一点:
# 假设inputs和targets是你的数据和标签
inputs = inputs.to(device)
targets = targets.to(device)
# 模型的输出也将在同一设备上
outputs = model(inputs)
# 你可以直接在设备上计算损失并反向传播
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
8.6
- 在中,函数用于生成一个一维张量(),其值从指定的起始值开始,以指定的步长递增,直到但不包括指定的终止值。这个函数类似于内置的 函数,但返回的是张量而不是列表。
torch.arange(start=0, end, step=1, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
#start (float, 可选) – 序列的起始值,默认为0。
#end (float) – 序列的终止值(不包含)。
#step (float, 可选) – 序列中每个元素之间的间隔,默认为1。
#out (Tensor, 可选) – 输出张量。
#dtype (torch.dtype, 可选) – 返回张量的数据类型。
#layout (torch.layout, 可选) – 返回张量的内存布局。
#device (torch.device, 可选) – 返回张量的设备。
#requires_grad (bool, 可选) – 是否需要计算梯度。
8.7
- 是 中的一个函数,用于从 数组创建一个 张量()。这个函数的主要用途是方便地在 和
import numpy as np
import torch
# 创建一个 NumPy 数组
numpy_array = np.array([[1, 2, 3], [4, 5, 6]])
# 使用 torch.from_numpy 从 NumPy 数组创建 PyTorch 张量
torch_tensor = torch.from_numpy(numpy_array)
print(torch_tensor)
8.8
是 中所有神经网络模型的基类,它提供了模型定义和操作的基本功能。下面逐行解释一下 类在
- 继承:所有自定义的神经网络模块都需要继承 ,并且需要在初始化函数 中调用父类的初始化方法。
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__() # 调用父类 nn.Module 的初始化方法
- 定义层:在
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size) # 定义卷积层
self.fc1 = nn.Linear(in_features, out_features) # 定义全连接层
- 前向传播:重写
def forward(self, x):
x = self.conv1(x) # 使用定义的卷积层
x = F.relu(x) # 应用激活函数
x = self.fc1(x) # 使用定义的全连接层
return x # 返回输出
- 模型参数管理:
model = MyModel()
torch.save(model.state_dict(), 'model.pth') # 保存模型参数
model.load_state_dict(torch.load('model.pth')) # 加载模型参数
- 设备管理: 提供了将模型转移到不同设备(如 和 )的方法。
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device) # 将模型转移到指定设备
- 子模块:
self.layer1 = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size),
nn.ReLU(),
nn.MaxPool2d(kernel_size)
) # 使用 Sequential 组合多个层
8.9
- 是 中的一个函数,用于创建填充了零的张量()。
torch.zeros(*sizes, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
"""
*sizes:定义了张量的形状的整数序列(元组或列表)。例如,(3, 4) 会创建一个 3x4 的二维张量。
out:一个可选的输出张量,它必须是正确的形状和类型。如果提供,则此函数将结果写入它并返回它。
dtype:返回张量的所需数据类型(默认为 torch.float32)。
layout:返回张量的所需内存布局(默认为 torch.strided)。
device:返回张量的所需设备(默认为当前设备)。
requires_grad:如果设置为 True,则张量将需要计算其梯度(默认为 False)。
"""
8.10
- 是 中用于创建张量()的一个函数。这个函数可以从各种数据类型(如列表、元组、
import torch
# 从列表创建张量
x = torch.tensor([1, 2, 3])
print(x)
# 从 NumPy 数组创建张量
import numpy as np
y = np.array([[1, 2], [3, 4]])
z = torch.tensor(y)
print(z)
# 创建一个指定数据类型的张量
a = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float64)
print(a)
# 创建一个需要计算梯度的张量
b = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
print(b)
8.11
- 在中, 是一个常用于改变张量()形状的方法。这个方法的作用是在指定的维度 上增加一个大小为1的维度。这并不会改变张量中的元素总数,而只是改变了张量的维度数量。
- 具体来说, 会在张量的 维度之前插入一个大小为1的维度。如果 是一个负数,那么它会被视为从后往前数的维度。
import torch
# 创建一个一维张量
x = torch.tensor([1, 2, 3])
print(x.shape) # 输出:torch.Size([3])
# 在第0维(最左边)之前增加一个维度
y = x.unsqueeze(0)
print(y.shape) # 输出:torch.Size([1, 3])
# 在第1维(现在是最右边)之前增加一个维度
z = y.unsqueeze(1)
print(z.shape) # 输出:torch.Size([1, 1, 3])
# 同样的效果,但是使用-1作为维度(从后往前数第一个维度)
w = y.unsqueeze(-1)
print(w.shape) # 输出:torch.Size([1, 3, 1])
8.12
- 在中,是一个常用于模块()内部的方法,用于注册一个不参与梯度计算的张量(),但希望它作为模型状态的一部分被保存和加载。通常,我们不会在中注册的张量上调用,因为它们是常数或不需要更新的参数。
- 当你有一个张量,它对于模型的前向传播是必要的,但不是模型的参数(即不需要通过优化器进行更新),你可以使用来注册它。这样,当你保存和加载模型的状态字典()时,这个张量也会被保存和加载。
8.13
- 在中,是一个张量()的方法,用于重新排列张量的维度。它接收一个由整数组成的元组,指定了原始张量维度的新顺序。方法不会改变张量的数据,只是改变了张量维度的顺序。
- 例如,假设我们有一个形状为 () 的三维张量 ,其中 是批量大小, 是序列长度, 是特征数量。如果我们想要将 和 的维度交换,我们可以使用
import torch
# 假设 x 是一个形状为 (batch_size, sequence_length, features) 的张量
x = torch.randn(batch_size, sequence_length, features)
# 使用 permute 方法交换 sequence_length 和 features 的维度
# 新的维度顺序是 (batch_size, features, sequence_length)
x_permuted = x.permute(0, 2, 1)
# 现在 x_permuted 的形状是 (batch_size, features, sequence_length)
- 在卷积神经网络()中,方法经常用于改变张量的维度,以便能够正确地输入到卷积层中。例如,在处理自然语言处理()任务时,输入数据通常是二维的(),但当我们想要应用一维卷积层()时,我们通常需要添加一个额外的特征维度(例如,将嵌入向量的维度视为特征)。然后,我们可能需要使用permute 来改变维度顺序,以满足 的输入要求(通常是 ())。
# 假设 embeddings 是一个形状为 (batch_size, sequence_length, embedding_dim) 的张量
# 我们想要将其输入到一个 nn.Conv1d 层中
# 如果 nn.Conv1d 期望的输入形状是 (batch_size, in_channels, sequence_length)
# 我们需要使用 permute 来改变 embeddings 的维度顺序
embeddings_for_conv = embeddings.permute(0, 2, 1)
# 现在 embeddings_for_conv 的形状是 (batch_size, embedding_dim, sequence_length)
# 它可以被正确地输入到 nn.Conv1d 层中
8.14
- 在中,方法用于交换张量中的两个维度。这是一个非常实用的操作,特别在处理多维数据时,可以帮助我们重新排列数据的维度以满足特定的需求或算法的要求。
以下是关于$ .transpose() $方法的详细解释:
方法定义
是要交换的两个维度的索引。索引从开始,表示第一个维度,依此类推。
import torch
x = torch.randn(2, 3, 4) # 创建一个形状为 [2, 3, 4] 的张量
y = x.transpose(0, 1) # 交换第一个和第二个维度
print(y.shape) # 输出:torch.Size([3, 2, 4])
注意事项
- 在交换维度时,不需要考虑其他维度的大小或顺序,只需要指定要交换的两个维度的索引即可。
- 交换维度不会改变张量中的数据,只是改变了维度的顺序。
与 .permute() 的区别
- 与 类似, 也是用于重新排列张量维度的函数。但 更加灵活,可以一次性重新排列所有维度,而不仅仅是两个。在使用 时,需要提供一个包含所有维度索引的元组,指定新的维度顺序。相比之下,
8.15
- 方法在 中用于从计算图中分离张量,以防止反向传播时计算梯度。具体来说,当你对一个张量调用时,它会返回一个新的张量,该张量与原始张量共享数据,但不会记录计算图。这意味着对这个新张量的操作不会影响原始张量的梯度。
- 在上下文中,
class FixedEmbedding(nn.Module):
def __init__(self, c_in, d_model):
super(FixedEmbedding, self).__init__()
# 创建一个形状为 (c_in, d_model) 的零张量 w,并将其数据类型设置为浮点型
w = torch.zeros(c_in, d_model).float()
# 设置 w 的梯度计算为 False,即在反向传播时不更新该张量的值
w.require_grad = False
# 创建一个形状为 (c_in, 1) 的位置张量,包含从 0 到 c_in-1 的序列
position = torch.arange(0, c_in).float().unsqueeze(1)
# 创建一个形状为 (d_model//2,) 的除数张量,其中每个元素是一个指数函数的结果
div_term = (torch.arange(0, d_model, 2).float() * -(math.log(10000.0) / d_model)).exp()
# 使用正弦函数为偶数列赋值
w[:, 0::2] = torch.sin(position * div_term)
# 使用余弦函数为奇数列赋值
w[:, 1::2] = torch.cos(position * div_term)
# 创建一个嵌入层,其权重初始化为上述计算的 w,并设置为不可训练
self.emb = nn.Embedding(c_in, d_model)
self.emb.weight = nn.Parameter(w, requires_grad=False)
def forward(self, x):
# 在前向传播时,返回嵌入层的输出,并使用 detach 方法以确保不计算梯度
return self.emb(x).detach() # 使用 detach() 确保返回的嵌入不参与梯度计算
8.16
- 在 中, 是 的一个子类,用于告知 它包含的张量是一个需要训练的参数。所有包含在 子类中的 对象会自动注册为模块的参数,并在调用
9.pandas
9.1 read_csv
- pandas 的 read_csv 函数是用于从 CSV (Comma Separated Values) 文件中读取数据并加载到
DataFrame 对象的。CSV 文件是一种常用的表格数据存储格式,它使用逗号(或其他分隔符)来分隔单元格内的数据。
常用参数
- filepath_or_buffer:文件路径或类似文件的对象,如 URL、字符串或文件句柄。
- sep 或 delimiter:字段分隔符,默认为逗号 ‘,’。
- header:用作列名的行号,默认为 0(第一行)。如果文件没有标题行,可以设置为 None 并手动提供列名。
- index_col:用作行索引的列编号或列名,可以是单个列或列列表。
- usecols:返回的列编号或列名列表。
- dtype:每列的数据类型,可以是类型名称或类型字典。
- nrows:要读取的行数。
- skiprows:需要忽略的行数或要跳过的行号列表。
- parse_dates:需要解析为日期的列编号或列名列表,或 True(表示解析所有列)。
- date_parser:用于解析日期的函数。
- na_values:表示缺失值的额外字符串列表。
- keep_default_na:是否包括 pandas 默认的 NaN 值(如空字符串或 ‘NaN’)。
- thousands:千位分隔符,如 ‘,’ 或 ‘.’。
- decimal:小数点字符,默认为 ‘.’。
- encoding:用于解码文件的字符编码。
- squeeze:如果数据只包含一列,则返回 Series 而不是 DataFrame。
import pandas as pd
#读取 CSV 文件并加载到 DataFrame:
df = pd.read_csv('data.csv')
df = pd.read_csv('data.csv', sep=';')
#指定分隔符(例如,使用分号 ; 而不是逗号 ,):
df = pd.read_csv('data.csv', header=None)
#跳过第一行(不将其用作标题行):
df = pd.read_csv('data.csv', skiprows=2, names=['col1', 'col2', 'col3'])
#跳过前两行并手动指定列名:
df = pd.read_csv('data.csv', usecols=[0, 1])
#读取指定列(例如,只读取前两列):
df = pd.read_csv('data.csv', nrows=10)
#读取指定数量的行(例如,只读取前 10 行):
df = pd.read_csv('data.csv', parse_dates=['date'])
#解析日期列(例如,将 'date' 列解析为日期):
9.2 columns
- 在pandas库中,DataFrame对象有一个columns属性,它返回一个Index对象,表示该DataFrame的列标签(列名)。
import pandas as pd
# 创建一个简单的DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df_raw = pd.DataFrame(data)
# 输出列名
print(df_raw.columns)
9.3 pd.to_datetime
- pd.to_datetime 是 Pandas 库中的一个函数,用于将各种输入类型(如字符串、数字、日期列表、Python 的datetime 对象等)转换为 Pandas 的 datetime类型。这个函数在处理时间序列数据时非常有用,因为它能够自动解析许多不同的日期和时间格式。
import pandas as pd
#将字符串转换成日期
dates = ['2023-01-01', '2023-01-02', '2023-01-03']
dt_dates = pd.to_datetime(dates)
print(dt_dates)
#处理非标准格式的日期字符串
#如果你有一个非标准的日期格式,你可以通过 format 参数来指定它。
dates = ['01/01/2023', '02/01/2023', '03/01/2023']
dt_dates = pd.to_datetime(dates, format='%m/%d/%Y')
print(dt_dates)
import pandas as pd
#将 Series 转换为日期
df = pd.DataFrame({
'date_strings': ['2023-01-01', '2023-01-02', '2023-01-03']
})
df['dates'] = pd.to_datetime(df['date_strings'])
print(df)
#转换包含错误数据的 Series
#如果某些日期无法被解析,pd.to_datetime 会将它们转换为 NaT(Not a Time),这是 Pandas 中表示缺失时间戳的特殊值。
dates = ['2023-01-01', 'not a date', '2023-01-03']
dt_dates = pd.to_datetime(dates, errors='coerce')
print(dt_dates)
#使用 infer_datetime_format 参数
#在某些情况下,Pandas 可以自动推断日期格式。你可以通过设置 infer_datetime_format=True 来尝试让 Pandas 自动解析日期格式。
dates = ['2023-01-01', '2023-01-02', '2023-01-03']
dt_dates = pd.to_datetime(dates, infer_datetime_format=True)
print(dt_dates)
9.4 to_offset
- 在 pandas 中,to_offset函数通常与日期和时间相关的操作相关,特别是在处理时间序列数据(如时间序列重采样)时。to_offset 函数可以将字符串或DateOffset 对象转换为一个有效的 DateOffset 实例,这有助于在时间序列数据上进行精确的时间偏移。
- to_offset 不是一个直接暴露给用户的函数,它通常在 pandas 内部使用。用户在处理时间序列时,更常见的是使用pd.to_timedelta 或 pd.DateOffset。
- pd.to_timedelta 用于将字符串或数字转换为时间差(timedelta)对象,而 pd.DateOffset则用于表示相对时间偏移,如“1天”、“1月”等。
- 如果你想要创建一个时间偏移,你可以直接使用 pd.DateOffset 或其子类,例如pd.offsets.Day、pd.offsets.MonthBegin 等。
import pandas as pd
# 创建一个表示1天偏移的 DateOffset 对象
one_day_offset = pd.DateOffset(days=1)
# 或者使用更具体的子类
one_day_offset_specific = pd.offsets.Day(1)
# 使用 DateOffset
some_date = pd.Timestamp('2023-01-01')
new_date = some_date + one_day_offset
print(new_date) # 输出:2023-01-02 00:00:00
10.scikit-learn
10.1 StandardScaler
- 位于scikit-learn库中的preprocessing模块。它是一个常用的数据标准化方法,主要用于将数据转换为均值为0,标准差为1的标准正态分布。以下是StandardScaler的常用方法:
1.fit(X, y=None)
- 计算数据的均值和标准差。这里的X是特征数据,y通常可以忽略,因为StandardScaler只关注特征。
2.transform(X, y=‘deprecated’, copy=True)
- 使用fit()方法计算出的均值和标准差来转换数据。将每个数据点减去均值,再除以标准差,从而得到标准化后的数据。
3.**fit_transform(X, y=None, fit_params)
- 先调用fit()方法计算均值和标准差,然后调用transform()方法进行转换。这相当于连续调用fit()和transform(),但更节省内存。
4.get_params(deep=True)
- 获取此估计器的参数。
5.**set_params(params)
- 设置此估计器的参数。
6.inverse_transform(X, copy=True)
- 将标准化后的数据转换回原始比例。这在某些情况下可能很有用,比如当你需要将模型的预测值转换回原始数据比例时。
使用StandardScaler进行数据标准化的步骤大致如下:
- 导入StandardScaler模块:from sklearn.preprocessing import StandardScaler
- 创建StandardScaler实例:scaler = StandardScaler()
- 拟合数据:scaler.fit(train_data),其中train_data是训练数据的特征
- 转换数据:standardized_data =scaler.transform(data_to_transform),其中data_to_transform是需要转换的数据(可以是训练数据、测试数据或其他数据)
11.numpy
11.1 concatenate
- 在NumPy中,concatenate 函数用于将两个或多个数组按照指定的轴(axis)连接起来。这个函数的基本语法如下:
numpy.concatenate((a1, a2, ...), axis=0, out=None)
#a1, a2, ...:需要连接的数组序列。
#axis:连接的轴。0表示第一个维度(行),1表示第二个维度(列),依此类推。
#out:一个可选参数,用于指定输出数组。通常不需要这个参数。
import numpy as np
#沿着第一个维度(axis=0)连接数组
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.concatenate((a, b), axis=0)
print(c)
# 输出:
# [[1 2]
# [3 4]
# [5 6]]
import numpy as np
#沿着第二个维度(axis=1)连接数组
#注意:要连接的数组在第二维度上(列数)的维度必须相同。
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
# 由于 b 只有一个行,所以需要先进行 reshape 操作来匹配 a 的形状
b = b.reshape(1, -1) # 这将 b 变为 [[5, 6]]
c = np.concatenate((a, b.T), axis=1) # 注意这里使用 b.T 来转置 b,使其成为一个列向量
print(c)
# 输出:
# [[1 2 5]
# [3 4 6]]
12.@property
- 在Python的面向对象编程中,@property是一个内置的装饰器(decorator),它用于将方法“转化”为属性。这意味着你可以像访问数据属性那样访问方法,但实际上是调用了被@property 装饰的方法。
- @property 通常与三个特殊的方法一起使用:getter(默认),setter 和 deleter。
#getter
class MyClass:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
obj = MyClass(10)
print(obj.value) # 输出:10
#setter
class MyClass:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
if new_value >= 0:
self._value = new_value
else:
raise ValueError("Value must be non-negative")
obj = MyClass(10)
obj.value = 20 # 正常设置
print(obj.value) # 输出:20
obj.value = -1 # 抛出 ValueError
#deleter
class MyClass:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
@value.deleter
def value(self):
del self._value
obj = MyClass(10)
del obj.value # 调用 deleter 方法
13.call
定义:在Python类中,__call__方法是一个特殊的实例方法,它的功能类似于在类中重载()运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。
参数:__call__方法可以接受任意数量的参数,包括位置参数和关键字参数。这些参数由调用者传入,并在__call__方法内部进行处理。
用途:
- 允许类的实例像函数一样被调用,增加了类的灵活性。
- 可以用于实现基于类的装饰器,记录函数被调用的次数等。
- 在一些框架和库中,如PyTorch,__call__方法也被广泛使用。
示例:
class Adder:
def __init__(self, value=0):
self.data = value
def __call__(self, x, y):
return self.data + x + y
add = Adder()
print(add(1, 3)) # 输出 4
print(add(2, 4)) # 输出 6
注意事项:
- __call__方法的名字是固定的,不能随意更改。
- 与__init__方法不同,__call__方法在对象创建之后被调用,用于改变对象的属性值或执行其他操作。
14.repr
- repr 是 Python 中的一个特殊方法(也称为“魔法方法”或“双下划线方法”),它返回一个对象的“官方”字符串表示,通常包含足够的信息以便重新创建该对象的代码。这个表示应该是一个有效的Python 表达式,如果可能的话,它应该可以被 eval() 函数评估以产生原始对象。
- repr 方法应该返回一个字符串,该字符串表示对象的“官方”或“无歧义”的字符串形式。这通常意味着它应该返回足够的细节,以便了解对象的类型和状态,而不仅仅是它的值。
- 下面是一个简单的例子,展示了一个自定义类如何定义 repr 方法:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name={self.name!r}, age={self.age})"
# 创建一个 Person 对象
p = Person("Alice", 30)
# 打印对象的 repr 表示
print(repr(p)) # 输出:Person(name='Alice', age=30)
# 注意:你也可以直接打印对象,因为 print 函数默认会调用 repr 函数
print(p) # 输出:Person(name='Alice', age=30)