【自然語言處理(NLP)】基于Transformer架構的預訓練語言模型:BERT 訓練之數據集處理、訓練代碼實現

文章目錄

  • 介紹
  • BERT 訓練之數據集處理
    • BERT 原理及模型代碼實現
    • 數據集處理
      • 導包
      • 加載數據
      • 生成下一句預測任務的數據
      • 從段落中獲取nsp數據
      • 生成遮蔽語言模型任務的數據
      • 從token中獲取mlm數據
      • 將文本轉換為預訓練數據集
      • 創建Dataset
      • 加載WikiText-2數據集
  • BERT 訓練代碼實現
    • 導包
    • 加載數據
    • 構建BERT模型
    • 模型損失
    • 訓練
    • 獲取BERT編碼器

個人主頁:道友老李
歡迎加入社區:道友老李的學習社區

介紹

**自然語言處理(Natural Language Processing,NLP)**是計算機科學領域與人工智能領域中的一個重要方向。它研究的是人類(自然)語言與計算機之間的交互。NLP的目標是讓計算機能夠理解、解析、生成人類語言,并且能夠以有意義的方式回應和操作這些信息。

NLP的任務可以分為多個層次,包括但不限于:

  1. 詞法分析:將文本分解成單詞或標記(token),并識別它們的詞性(如名詞、動詞等)。
  2. 句法分析:分析句子結構,理解句子中詞語的關系,比如主語、謂語、賓語等。
  3. 語義分析:試圖理解句子的實際含義,超越字面意義,捕捉隱含的信息。
  4. 語用分析:考慮上下文和對話背景,理解話語在特定情境下的使用目的。
  5. 情感分析:檢測文本中表達的情感傾向,例如正面、負面或中立。
  6. 機器翻譯:將一種自然語言轉換為另一種自然語言。
  7. 問答系統:構建可以回答用戶問題的系統。
  8. 文本摘要:從大量文本中提取關鍵信息,生成簡短的摘要。
  9. 命名實體識別(NER):識別文本中提到的特定實體,如人名、地名、組織名等。
  10. 語音識別:將人類的語音轉換為計算機可讀的文字格式。

NLP技術的發展依賴于算法的進步、計算能力的提升以及大規模標注數據集的可用性。近年來,深度學習方法,特別是基于神經網絡的語言模型,如BERT、GPT系列等,在許多NLP任務上取得了顯著的成功。隨著技術的進步,NLP正在被應用到越來越多的領域,包括客戶服務、智能搜索、內容推薦、醫療健康等。

BERT 訓練之數據集處理

BERT 原理及模型代碼實現

【自然語言處理(NLP)】基于Transformer架構的預訓練語言模型:BERT 原理及代碼實現

數據集處理

導包

import os
import random
import torch
import dltools

加載數據

def _read_wiki(data_dir):file_name = os.path.join(data_dir, 'wiki.train.tokens')with open(file_name, 'r',encoding="utf-8") as f:lines = f.readlines()# 大寫字母轉換為小寫字母paragraphs = [line.strip().lower().split(' . ') for line in lines if len(line.split(' . ')) >= 2]random.shuffle(paragraphs)return paragraphs_read_wiki('./wikitext-2')

在這里插入圖片描述

生成下一句預測任務的數據

def _get_next_sentence(sentence, next_sentence, paragraphs):if random.random() < 0.5:is_next = Trueelse:# paragraphs是三重列表的嵌套next_sentence = random.choice(random.choice(paragraphs))is_next = Falsereturn sentence, next_sentence, is_next

從段落中獲取nsp數據

def _get_nsp_data_from_paragraph(paragraph, paragraphs, vocab, max_len):nsp_data_from_paragraph = []for i in range(len(paragraph) - 1):tokens_a, tokens_b, is_next = _get_next_sentence(paragraph[i], paragraph[i + 1], paragraphs)# 考慮1個'<cls>'詞元和2個'<sep>'詞元if len(tokens_a) + len(tokens_b) + 3 > max_len:continuetokens, segments = dltools.get_tokens_and_segments(tokens_a, tokens_b)nsp_data_from_paragraph.append((tokens, segments, is_next))return nsp_data_from_paragraph

生成遮蔽語言模型任務的數據

  1. 為遮蔽語言模型的輸入創建新的詞元副本,其中輸入可能包含替換的mask或隨機詞元
  2. 打亂后用于在遮蔽語言模型任務中獲取15%的隨機詞元進行預測
  3. 80%的時間:將詞替換為mask詞元
  4. 10%的時間:保持詞不變
  5. 10%的時間:用隨機詞替換該詞
def _replace_mlm_tokens(tokens, candidate_pred_positions, num_mlm_preds,vocab):# 為遮蔽語言模型的輸入創建新的詞元副本,其中輸入可能包含替換的“<mask>”或隨機詞元mlm_input_tokens = [token for token in tokens]pred_positions_and_labels = []# 打亂后用于在遮蔽語言模型任務中獲取15%的隨機詞元進行預測random.shuffle(candidate_pred_positions)for mlm_pred_position in candidate_pred_positions:if len(pred_positions_and_labels) >= num_mlm_preds:breakmasked_token = None# 80%的時間:將詞替換為“<mask>”詞元if random.random() < 0.8:masked_token = '<mask>'else:# 10%的時間:保持詞不變if random.random() < 0.5:masked_token = tokens[mlm_pred_position]# 10%的時間:用隨機詞替換該詞else:masked_token = random.choice(vocab.idx_to_token)mlm_input_tokens[mlm_pred_position] = masked_tokenpred_positions_and_labels.append((mlm_pred_position, tokens[mlm_pred_position]))return mlm_input_tokens, pred_positions_and_labels

從token中獲取mlm數據

在遮蔽語言模型任務中不會預測特殊詞元

def _get_mlm_data_from_tokens(tokens, vocab):candidate_pred_positions = []# tokens是一個字符串列表for i, token in enumerate(tokens):# 在遮蔽語言模型任務中不會預測特殊詞元if token in ['<cls>', '<sep>']:continuecandidate_pred_positions.append(i)# 遮蔽語言模型任務中預測15%的隨機詞元num_mlm_preds = max(1, round(len(tokens) * 0.15))mlm_input_tokens, pred_positions_and_labels = _replace_mlm_tokens(tokens, candidate_pred_positions, num_mlm_preds, vocab)pred_positions_and_labels = sorted(pred_positions_and_labels,key=lambda x: x[0])pred_positions = [v[0] for v in pred_positions_and_labels]mlm_pred_labels = [v[1] for v in pred_positions_and_labels]return vocab[mlm_input_tokens], pred_positions, vocab[mlm_pred_labels]

將文本轉換為預訓練數據集

  1. valid_lens不包括’'的計數
  2. 填充詞元的預測將通過乘以0權重在損失中過濾掉
def _pad_bert_inputs(examples, max_len, vocab):max_num_mlm_preds = round(max_len * 0.15)all_token_ids, all_segments, valid_lens,  = [], [], []all_pred_positions, all_mlm_weights, all_mlm_labels = [], [], []nsp_labels = []for (token_ids, pred_positions, mlm_pred_label_ids, segments,is_next) in examples:all_token_ids.append(torch.tensor(token_ids + [vocab['<pad>']] * (max_len - len(token_ids)), dtype=torch.long))all_segments.append(torch.tensor(segments + [0] * (max_len - len(segments)), dtype=torch.long))# valid_lens不包括'<pad>'的計數valid_lens.append(torch.tensor(len(token_ids), dtype=torch.float32))all_pred_positions.append(torch.tensor(pred_positions + [0] * (max_num_mlm_preds - len(pred_positions)), dtype=torch.long))# 填充詞元的預測將通過乘以0權重在損失中過濾掉all_mlm_weights.append(torch.tensor([1.0] * len(mlm_pred_label_ids) + [0.0] * (max_num_mlm_preds - len(pred_positions)),dtype=torch.float32))all_mlm_labels.append(torch.tensor(mlm_pred_label_ids + [0] * (max_num_mlm_preds - len(mlm_pred_label_ids)), dtype=torch.long))nsp_labels.append(torch.tensor(is_next, dtype=torch.long))return (all_token_ids, all_segments, valid_lens, all_pred_positions,all_mlm_weights, all_mlm_labels, nsp_labels)

創建Dataset

  1. 輸入paragraphs[i]是代表段落的句子字符串列表
  2. 而輸出paragraphs[i]是代表段落的句子列表,其中每個句子都是詞元列表
  3. 獲取下一句子預測任務的數據
  4. 獲取遮蔽語言模型任務的數據
  5. 填充輸入
class _WikiTextDataset(torch.utils.data.Dataset):def __init__(self, paragraphs, max_len):# 輸入paragraphs[i]是代表段落的句子字符串列表;# 而輸出paragraphs[i]是代表段落的句子列表,其中每個句子都是詞元列表paragraphs = [dltools.tokenize(paragraph, token='word') for paragraph in paragraphs]sentences = [sentence for paragraph in paragraphsfor sentence in paragraph]self.vocab = dltools.Vocab(sentences, min_freq=5, reserved_tokens=['<pad>', '<mask>', '<cls>', '<sep>'])# 獲取下一句子預測任務的數據examples = []for paragraph in paragraphs:examples.extend(_get_nsp_data_from_paragraph(paragraph, paragraphs, self.vocab, max_len))# 獲取遮蔽語言模型任務的數據examples = [(_get_mlm_data_from_tokens(tokens, self.vocab)+ (segments, is_next))for tokens, segments, is_next in examples]# 填充輸入(self.all_token_ids, self.all_segments, self.valid_lens,self.all_pred_positions, self.all_mlm_weights,self.all_mlm_labels, self.nsp_labels) = _pad_bert_inputs(examples, max_len, self.vocab)def __getitem__(self, idx):return (self.all_token_ids[idx], self.all_segments[idx],self.valid_lens[idx], self.all_pred_positions[idx],self.all_mlm_weights[idx], self.all_mlm_labels[idx],self.nsp_labels[idx])def __len__(self):return len(self.all_token_ids)

加載WikiText-2數據集

def load_data_wiki(batch_size, max_len):"""加載WikiText-2數據集"""num_workers = dltools.get_dataloader_workers()data_dir = "./wikitext-2/"paragraphs = _read_wiki(data_dir)train_set = _WikiTextDataset(paragraphs, max_len)train_iter = torch.utils.data.DataLoader(train_set, batch_size,shuffle=True, num_workers=num_workers)return train_iter, train_set.vocabbatch_size, max_len = 512, 64
train_iter, vocab = load_data_wiki(batch_size, max_len)for (tokens_X, segments_X, valid_lens_x, pred_positions_X, mlm_weights_X,mlm_Y, nsp_y) in train_iter:print(tokens_X.shape, segments_X.shape, valid_lens_x.shape,pred_positions_X.shape, mlm_weights_X.shape, mlm_Y.shape,nsp_y.shape)break
torch.Size([512, 64]) torch.Size([512, 64]) torch.Size([512]) torch.Size([512, 10]) torch.Size([512, 10]) torch.Size([512, 10]) torch.Size([512])
len(vocab)
20256

BERT 訓練代碼實現

導包

import torch
from torch import nn
import dltools

加載數據

dltools中加載本地wiki文件,請自行修改路徑 ./data/wikitext-2

batch_size, max_len = 1, 64
# dltools中加載本地wiki文件,請自行修改路徑 ./data/wikitext-2
train_iter, vocab = dltools.load_data_wiki(batch_size, max_len)# tokens, segments, valid_lens, pred_positions, mlm_weights,mlm, nsp
for i in train_iter:break
i

在這里插入圖片描述

構建BERT模型

net = dltools.BERTModel(len(vocab), num_hiddens=128, norm_shape=[128],ffn_num_input=128, ffn_num_hiddens=256, num_heads=2,num_layers=2, dropout=0.2, key_size=128, query_size=128,value_size=128, hid_in_features=128, mlm_in_features=128,nsp_in_features=128)
devices = dltools.try_all_gpus()

模型損失

  1. 前向傳播
  2. 計算遮蔽語言模型損失
  3. 計算下一句子預測任務的損失
loss = nn.CrossEntropyLoss()def _get_batch_loss_bert(net, loss, vocab_size, tokens_X,segments_X, valid_lens_x,pred_positions_X, mlm_weights_X,mlm_Y, nsp_y):# 前向傳播_, mlm_Y_hat, nsp_Y_hat = net(tokens_X, segments_X,valid_lens_x.reshape(-1),pred_positions_X)# 計算遮蔽語言模型損失mlm_l = loss(mlm_Y_hat.reshape(-1, vocab_size), mlm_Y.reshape(-1)) * mlm_weights_X.reshape(-1, 1)mlm_l = mlm_l.sum() / (mlm_weights_X.sum() + 1e-8)# 計算下一句子預測任務的損失nsp_l = loss(nsp_Y_hat, nsp_y)l = mlm_l + nsp_lreturn mlm_l, nsp_l, l

訓練

遮蔽語言模型損失的和,下一句預測任務損失的和,句子對的數量,計數

def train_bert(train_iter, net, loss, vocab_size, devices, num_steps):net = nn.DataParallel(net, device_ids=devices).to(devices[0])trainer = torch.optim.Adam(net.parameters(), lr=0.01)step, timer = 0, dltools.Timer()animator = dltools.Animator(xlabel='step', ylabel='loss',xlim=[1, num_steps], legend=['mlm', 'nsp'])# 遮蔽語言模型損失的和,下一句預測任務損失的和,句子對的數量,計數metric = dltools.Accumulator(4)num_steps_reached = Falsewhile step < num_steps and not num_steps_reached:for tokens_X, segments_X, valid_lens_x, pred_positions_X,mlm_weights_X, mlm_Y, nsp_y in train_iter:tokens_X = tokens_X.to(devices[0])segments_X = segments_X.to(devices[0])valid_lens_x = valid_lens_x.to(devices[0])pred_positions_X = pred_positions_X.to(devices[0])mlm_weights_X = mlm_weights_X.to(devices[0])mlm_Y, nsp_y = mlm_Y.to(devices[0]), nsp_y.to(devices[0])trainer.zero_grad()timer.start()mlm_l, nsp_l, l = _get_batch_loss_bert(net, loss, vocab_size, tokens_X, segments_X, valid_lens_x,pred_positions_X, mlm_weights_X, mlm_Y, nsp_y)l.backward()trainer.step()metric.add(mlm_l, nsp_l, tokens_X.shape[0], 1)timer.stop()animator.add(step + 1,(metric[0] / metric[3], metric[1] / metric[3]))step += 1if step == num_steps:num_steps_reached = Truebreakprint(f'MLM loss {metric[0] / metric[3]:.3f}, 'f'NSP loss {metric[1] / metric[3]:.3f}')print(f'{metric[2] / timer.sum():.1f} sentence pairs/sec on 'f'{str(devices)}')train_bert(train_iter, net, loss, len(vocab), devices, 500)

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

獲取BERT編碼器

def get_bert_encoding(net, tokens_a, tokens_b=None):tokens, segments = dltools.get_tokens_and_segments(tokens_a, tokens_b)token_ids = torch.tensor(vocab[tokens], device=devices[0]).unsqueeze(0)segments = torch.tensor(segments, device=devices[0]).unsqueeze(0)valid_len = torch.tensor(len(tokens), device=devices[0]).unsqueeze(0)encoded_X, _, _ = net(token_ids, segments, valid_len)return encoded_Xtokens_a = ['a', 'crane', 'is', 'flying']
encoded_text = get_bert_encoding(net, tokens_a)
# 詞元:'<cls>','a','crane','is','flying','<sep>'
encoded_text_cls = encoded_text[:, 0, :]
encoded_text_crane = encoded_text[:, 2, :]
encoded_text.shape, encoded_text_cls.shape, encoded_text_crane[0][:3]
(torch.Size([1, 6, 128]),torch.Size([1, 128]),tensor([-1.0005,  0.8355,  0.2930], grad_fn=<SliceBackward0>))
tokens_a, tokens_b = ['a', 'crane', 'driver', 'came'], ['he', 'just', 'left']
encoded_pair = get_bert_encoding(net, tokens_a, tokens_b)
# 詞元:'<cls>','a','crane','driver','came','<sep>','he','just',
# 'left','<sep>'
encoded_pair_cls = encoded_pair[:, 0, :]
encoded_pair_crane = encoded_pair[:, 2, :]
encoded_pair.shape, encoded_pair_cls.shape, encoded_pair_crane[0][:3]
(torch.Size([1, 10, 128]),torch.Size([1, 128]),tensor([-1.0168,  0.8235,  0.2141], grad_fn=<SliceBackward0>))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67796.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode435周賽T2貪心

題目描述 給你一個由字符 N、S、E 和 W 組成的字符串 s&#xff0c;其中 s[i] 表示在無限網格中的移動操作&#xff1a; N&#xff1a;向北移動 1 個單位。S&#xff1a;向南移動 1 個單位。E&#xff1a;向東移動 1 個單位。W&#xff1a;向西移動 1 個單位。 初始時&#…

【Numpy核心編程攻略:Python數據處理、分析詳解與科學計算】2.5 高級索引應用:圖像處理中的區域提取

2.5 高級索引應用&#xff1a;圖像處理中的區域提取 目錄/提綱 #mermaid-svg-BI09xc20YqcpUam7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-BI09xc20YqcpUam7 .error-icon{fill:#552222;}#mermaid-svg-BI09xc20…

ubuntu直接運行arm環境qemu-arm-static

qemu-arm-static 嵌入式開發有時會在ARM設備上使用ubuntu文件系統。開發者常常會面臨這樣一個問題&#xff0c;想預先交叉編譯并安裝一些應用程序&#xff0c;但是交叉編譯的環境配置以及依賴包的安裝十分繁瑣&#xff0c;并且容易出錯。想直接在目標板上進行編譯和安裝&#x…

通過Redisson構建延時隊列并實現注解式消費

目錄 一、序言二、延遲隊列實現1、Redisson延時消息監聽注解和消息體2、Redisson延時消息發布器3、Redisson延時消息監聽處理器 三、測試用例四、結語 一、序言 兩個月前接了一個4萬的私活&#xff0c;做一個線上商城小程序&#xff0c;在交易過程中不可避免的一個問題就是用戶…

MVC 文件夾:架構之美與實際應用

MVC 文件夾:架構之美與實際應用 引言 MVC(Model-View-Controller)是一種設計模式,它將應用程序分為三個核心組件:模型(Model)、視圖(View)和控制器(Controller)。這種架構模式不僅提高了代碼的可維護性和可擴展性,而且使得開發流程更加清晰。本文將深入探討MVC文…

【PyQt】lambda函數,實現動態傳遞參數

為什么需要 lambda&#xff1f; 在 PyQt5 中&#xff0c;clicked 信號默認會傳遞一個布爾值&#xff08;表示按鈕是否被選中&#xff09;。如果我們希望將按鈕的文本內容傳遞給槽函數&#xff0c;需要通過 lambda 函數顯式傳遞參數。 這樣可以實現將按鈕內容傳遞給槽函數&…

pytorch深度Q網絡

人工智能例子匯總&#xff1a;AI常見的算法和例子-CSDN博客 DQN 引入了深度神經網絡來近似Q函數&#xff0c;解決了傳統Q-learning在處理高維狀態空間時的瓶頸&#xff0c;尤其是在像 Atari 游戲這樣的復雜環境中。DQN的核心思想是使用神經網絡 Q(s,a;θ)Q(s, a; \theta)Q(s,…

Baklib構建高效協同的基于云的內容中臺解決方案

內容概要 隨著云計算技術的飛速發展&#xff0c;內容管理的方式也在不斷演變。企業面臨著如何在數字化轉型過程中高效管理和協同處理內容的新挑戰。為應對這些挑戰&#xff0c;引入基于云的內容中臺解決方案顯得尤為重要。 Baklib作為創新型解決方案提供商&#xff0c;致力于…

DeepSeek-R1 論文. Reinforcement Learning 通過強化學習激勵大型語言模型的推理能力

論文鏈接&#xff1a; [2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 實在太長&#xff0c;自行扔到 Model 里&#xff0c;去翻譯去提問吧。 工作原理&#xff1a; 主要技術&#xff0c;就是訓練出一些專有用途小模型&…

C++泛型編程指南03-CTAD

文章目錄 C17 自定義類型推斷指引&#xff08;CTAD&#xff09;深度解析一、基礎概念1. 核心作用2. 工作原理 二、標準庫中的 CTAD 應用1. 容器類型推導2. 智能指針推導3. 元組類型推導 三、自定義推導指引語法1. 基本語法結構2. 典型應用場景 四、推導指引設計模式1. 迭代器范…

deepseek+vscode自動化測試腳本生成

近幾日Deepseek大火,我這里也嘗試了一下,確實很強。而目前vscode的AI toolkit插件也已經集成了deepseek R1,這里就介紹下在vscode中利用deepseek幫助我們完成自動化測試腳本的實踐分享 安裝AI ToolKit并啟用Deepseek 微軟官方提供了一個針對AI輔助的插件,也就是 AI Toolk…

電介質超表面中指定渦旋的非線性生成

渦旋光束在眾多領域具有重要應用&#xff0c;但傳統光學器件產生渦旋光束的方式限制了其在集成系統中的應用。超表面的出現為渦旋光束的產生帶來了新的可能性&#xff0c;尤其是在非線性領域&#xff0c;盡管近些年來已經有一些研究&#xff0c;但仍存在諸多問題&#xff0c;如…

基于Springboot+mybatis+mysql+html圖書管理系統2

基于Springbootmybatismysqlhtml圖書管理系統2 一、系統介紹二、功能展示1.用戶登陸2.用戶主頁3.圖書查詢4.還書5.個人信息修改6.圖書管理&#xff08;管理員&#xff09;7.學生管理&#xff08;管理員&#xff09;8.廢除記錄&#xff08;管理員&#xff09; 三、數據庫四、其它…

重構字符串(767)

767. 重構字符串 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:string reorganizeString(string s){string res;//因為1 < s.length < 500 &#xff0c; uint64_t 類型足夠uint16_t n s.size();if (n 0) {return res;}unordere…

本地部署DeepSeek方法

本地部署完成后的效果如下圖&#xff0c;整體與chatgpt類似&#xff0c;只是模型在本地推理。 我們在本地部署主要使用兩個工具&#xff1a; ollamaopen-webui ollama是在本地管理和運行大模型的工具&#xff0c;可以直接在terminal里和大模型對話。open-webui是提供一個類…

游戲引擎 Unity - Unity 啟動(下載 Unity Editor、生成 Unity Personal Edition 許可證)

Unity Unity 首次發布于 2005 年&#xff0c;屬于 Unity Technologies Unity 使用的開發技術有&#xff1a;C# Unity 的適用平臺&#xff1a;PC、主機、移動設備、VR / AR、Web 等 Unity 的適用領域&#xff1a;開發中等畫質中小型項目 Unity 適合初學者或需要快速上手的開…

【開源免費】基于Vue和SpringBoot的公寓報修管理系統(附論文)

本文項目編號 T 186 &#xff0c;文末自助獲取源碼 \color{red}{T186&#xff0c;文末自助獲取源碼} T186&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、數據庫設計三、配套教程3.1 啟動教程3.2 講解視頻3.3 二次開發教程 四、功能截圖五、文案資料5.1 選題背景5.2 國內…

Haskell語言的多線程編程

Haskell語言的多線程編程 Haskell是一種基于函數式編程范式的編程語言&#xff0c;以其強大的類型系統和懶惰求值著稱。近年來&#xff0c;隨著多核處理器的發展&#xff0c;多線程編程變得日益重要。雖然Haskell最初并不是為了多線程而設計&#xff0c;但它的設計理念和工具集…

《蒼穹外賣》項目學習記錄-Day11訂單統計

根據起始時間和結束時間&#xff0c;先把begin放入集合中用while循環當begin不等于end的時候&#xff0c;讓begin加一天&#xff0c;這樣就把這個區間內的時間放到List集合。 查詢每天的訂單總數也就是查詢的時間段是大于當天的開始時間&#xff08;0點0分0秒&#xff09;小于…

【python】python油田數據分析與可視化(源碼+數據集)【獨一無二】

&#x1f449;博__主&#x1f448;&#xff1a;米碼收割機 &#x1f449;技__能&#x1f448;&#xff1a;C/Python語言 &#x1f449;專__注&#x1f448;&#xff1a;專注主流機器人、人工智能等相關領域的開發、測試技術。 【python】python油田數據分析與可視化&#xff08…