当前位置: 首页 > news >正文

不只是mini-react第二节:实现最简fiber

省流|总结

首先,我们编写JSX文件,并通过Babel等转换工具将其转化为createElement()函数的调用,最终生成虚拟 DOM(Vdom)格式。举个例子:

// 原始 JSX
const App = <div>hi-mini-react</div>;// Babel 编译后
const App = React.createElement("div",null,"hi-mini-react"
);// createElement 返回的虚拟 DOM 结构
const App = {type: "div",props: {children: ["hi-mini-react"]}
};

接下来,将转换后的虚拟 DOM 格式传入render函数,启动fiber流程,调用代码如下:

ReactDOM.createRoot(document.querySelector("#root")).render(App);

这段代码的作用是将整个App组件渲染到root容器中。

然后,fiber流程启动。render函数接收传入的虚拟 DOM,并构建root fiber节点,即fiber树的根节点,也是第一个工作单元nextWorkOfUnit。此时,fiber树中仅包含根节点的真实 DOM 引用(容器),其他节点尚未创建。root fiber节点具有如下特点:

  • 它的dom属性指向容器节点
  • 它的props.children包含整个应用的虚拟 DOM 结构
  • 它是整个fiber树的起点
nextWorkOfUnit = {dom: container,  // 真实 DOM 元素props: {children: [el],  // el 是传入的 App 虚拟 DOM},
};

接下来,启用workLoop任务调度系统。该系统通过requestIdleCallback在浏览器空闲时执行任务。当检测到剩余时间不足(小于 1ms)时,系统会主动让出主线程,从而实现任务的分片处理。

每次workLoop循环都会调用performWorkOfUnit,确保每次只处理一个fiber节点,实现任务的分片执行,这些任务可以随时中断与恢复。如果当前fiber节点的真实 DOM 引用不存在,performWorkOfUnit会在此fiber节点上添加dom引用,并将该fiber节点指向父级fiber节点,同时将其真实 DOM 引用传递给父级节点,形成如下结构:

//可视化展示
fiber节点                 真实DOM节点
┌─────────┐               ┌─────────┐
│div1 fiber│    dom引用    │  <div>  │
├─────────┤ ────────────► ├─────────┤
│parent   │               │         │
│dom      │               │         │
└─────────┘               └─────────┘▲                         ▲│                         ││ parent                  │ append(h1)│                         │
┌─────────┐               ┌─────────┐
│h1 fiber │    dom引用    │  <h1>   │
├─────────┤ ────────────► ├─────────┤
│parent   │               │         │
│dom      │               │         │
└─────────┘               └─────────┘//具体代码const dom = (fiber.dom = createDom(fiber.type));fiber.parent.dom.append(dom);

接着,performWorkOfUnit会调用两个函数:

  • updateProps:读取fiber节点中的虚拟 DOM 属性,并将其应用到对应的真实 DOM 上。
  • initChildren:将当前fiber节点传入,通过深度优先遍历的方式,将当前树形结构的fiber节点转化为链表结构。这样,大的fiber节点被拆分成一个个小的fiber节点,最终形成自上而下的树形结构。这种方式将整个渲染过程分割成一个个小任务,每个任务处理一个节点,从而实现任务的分片,避免了长任务阻塞主线程。

最后,遍历由initChildren构建的链表结构。需要注意的是,这里并不是先遍历再执行,而是边遍历边执行。

最简任务调度器workLoop(时间分片)

  1. 首次调用requestIdleCallback(workLoop),浏览器会在空闲时执行workLoop函数。
  2. workLoop函数会执行任务,并在每次执行任务时检查剩余空闲时间。
  3. 如果空闲时间不足 1 毫秒(timeRemaining() < 1),shouldYield会被设置为true,从而暂停当前任务。
  4. 然后,requestIdleCallback(workLoop)会被调用来请求下一次空闲时间,从而在下次空闲时继续执行未完成的任务。
  5. 每次任务执行时,taskId都会递增,用于标记任务的顺序。

什么是下次空闲时?这里的下次空闲时是指当前可能有高优先级任务需要处理,那么浏览器会暂停当前相对低优先级的任务而去处理这个高优先级任务,等这个高优先级任务处理完成后再回过头来执行低优先级任务,这就是时间分片。

let taskId = 1;
function workLoop(deadline) {taskId++;let shouldYield = false;while (!shouldYield) {// run taskconsole.log(`taskId:${taskId} run task`);// domshouldYield = deadline.timeRemaining() < 1;}requestIdleCallback(workLoop);// 再次调用
}requestIdleCallback(workLoop);//首次调用

实现最简fiber

执行顺序:

jsxbabel等工具编译createElement()render()workLoop()performWorkOfUnit()initChildren()树形结构转链表结构

1.通过createElement创建虚拟DOM树

createElement函数负责创建一个虚拟 DOM 对象。它的参数包括:type(元素类型,如divspan等),props(元素属性),children(元素的子节点)。在 React 中,children的处理方式非常重要,因为它决定了如何渲染子元素。createElement会递归处理children,如果children是文本节点,则直接将其转换为文本节点。如果是其他 React 元素或组件,它会再次调用createElement来生成对应的虚拟 DOM。

// 1. 首先通过createElement创建React元素
function createElement(type, props, ...children) {return {type,props: {...props,children: children.map((child) => {// 如果子元素是字符串,则创建文本节点return typeof child === "string" ? createTextNode(child) : child;}),},};
}
2.调用render函数,设置工作单元(fiber节点)nextWorkOfUnit

由前一节博客可以知道:

el为编写的jsx文件

container为传入的真实dom节点(在这里是root节点)

render函数是 React 渲染流程的起点。它会将传入的虚拟 DOM(el)渲染到指定的容器(container)中。在这个过程中,React 会为每个虚拟 DOM 元素创建一个 fiber 对象,并构建一个 fiber 树。每个 fiber 节点包含对应的 DOM 元素、propschildren等信息。这样 React 就能根据这个 fiber 树来管理和更新实际的 DOM。

// 2. 调用render函数开始渲染
function render(el, container) {// 创建第一个工作单元(root fiber)nextWorkOfUnit = {dom: container,//传入的真实root节点//虚拟dom元素props: {children: [el],},};
}
3.工作循环workLoop启动

workLoop是 React 渲染任务的调度器。它会根据浏览器的空闲时间进行任务调度,并决定什么时候更新哪些 fiber 节点。当浏览器空闲时,workLoop会通过requestIdleCallback触发任务执行。如果当前任务无法在空闲时间内完成,workLoop会暂停任务,等待下一次空闲时间。通过这种异步调度方式,React 可以避免阻塞主线程,确保渲染操作的流畅性。

// 3. 程序启动时就开始监听空闲时间
let nextWorkOfUnit = null;
function workLoop(deadline) {// deadline对象包含:// timeRemaining(): 返回当前空闲期剩余的毫秒数// didTimeout: 表示任务是否超时let shouldYield = false;while (!shouldYield && nextWorkOfUnit) {// 1. 条件判断:// - 是否需要让出主线程(shouldYield)// - 是否还有工作要做(nextWorkOfUnit)// 2. 处理当前工作单元并重新分配工作单元nextWorkOfUnit = performWorkOfUnit(nextWorkOfUnit);// 3. 检查是否需要让出主线程shouldYield = deadline.timeRemaining() < 1;}// 4. 无论是否完成所有工作,都继续监听下一个空闲时间requestIdleCallback(workLoop);
}
4.performWorkOfUnit重新分配工作单元

performWorkOfUnit是处理每个 fiber 节点的函数。在执行过程中,它会根据虚拟 DOM 的typeprops更新实际 DOM。当 fiber 节点包含子节点时,performWorkOfUnit会递归处理子节点。每处理完一个节点,performWorkOfUnit会返回该节点的下一个待处理工作单元,从而继续构建 DOM 树。

function performWorkOfUnit(fiber) {// 4 如果没有DOM节点,创建DOMif (!fiber.dom) {const dom = (fiber.dom = createDom(fiber.type));fiber.parent.dom.append(dom);//5 属性协调updateProps(dom, fiber.props);}
//---------------------------------------只关注前面即可// 6 处理子节点,构建fiber树initChildren(fiber)// 7 返回下一个工作单元,按照以下优先级:// 先找子节点if (fiber.child) {return fiber.child;}// 没有子节点找兄弟节点if (fiber.sibling) {return fiber.sibling;}// 都没有就回到父节点的兄弟节点return fiber.parent?.sibling;
}
5.updateProps 属性协调

updateProps 函数的核心目的是将 React 元素的属性(props)设置到实际的 DOM 节点上,而这里传入的dom实际上就是fiber.dom

function updateProps(dom, props) {Object.keys(props).forEach((key) => {if (key !== "children") {dom[key] = props[key];}});
}

举个简单的例子:

// 假设我们写了这样一个React元素
<div className="box" id="main">Hello</div>// React会将其转换为这样的对象
{type: 'div',props: {className: 'box',id: 'main',children: ['Hello']}
}// 然后在performWorkOfUnit中:
// 1. 首先创建DOM节点
const dom = document.createElement('div')  // <div></div>// 2. 调用updateProps设置属性
updateProps(dom, props)  
// 结果:<div class="box" id="main"></div>

可视化展示:

   React元素的属性      →     真实DOM节点的属性{                           <divclassName: 'box'class="box"id: 'main'         →       id="main"children: [...]            >}                           </div>React属性世界           DOM属性世界┌──────────┐          ┌──────────┐│  props   │   ═══>DOM    │└──────────┘          └──────────┘│                      │className: 'box'       class="box"onClick: fn         addEventListener
6.initChildren子节点处理

initChildren函数的任务是初始化虚拟 DOM 中的子节点。它会遍历子节点,并为每个子节点创建一个新的 fiber 节点。每个新创建的 fiber 节点将被添加到父节点的children数组中,从而形成树形结构。React 会继续递归处理每个子节点,直到所有子节点都被处理为止。

function initChildren(fiber) {const children = fiber.props.children;let prevChild = null;// 遍历所有子节点,建立fiber链接关系children.forEach((child, index) => {const newFiber = {type: child.type,props: child.props,child: null,//子级parent: fiber,//父级sibling: null,//兄弟级dom: null,};// 第一个子节点设为childif (index === 0) {fiber.child = newFiber;} else {// 其他子节点设为上一个节点的siblingprevChild.sibling = newFiber;}prevChild = newFiber;});
}
7.performWorkOfUnit将树形结构通过深度遍历转化为链表结构

performWorkOfUnit函数中,React 通过深度优先遍历将树形结构转化为链表结构。这种链表结构可以帮助 React 更高效地遍历并更新每个节点。每个 fiber 节点不仅包含当前节点的信息,还持有对父节点、兄弟节点的引用,这使得 React 可以灵活地在渲染过程中调整工作单元。

function performWorkOfUnit(fiber) {// ... 前面的代码省略 ...// 这三行代码决定了下一个工作单元,实际上就是在构建链表if (fiber.child) {return fiber.child;      // 1️⃣ 优先返回子节点}if (fiber.sibling) {return fiber.sibling;    // 2️⃣ 没有子节点就返回兄弟节点}return fiber.parent?.sibling;  // 3️⃣ 都没有就返回父节点的兄弟节点
}

源代码

// 创建文本节点
function createTextNode(text) {console.log("heiheihei!!!!!!!");return {type: "TEXT_ELEMENT",props: {nodeValue: text,children: [],},};
}// 创建React元素
// type: 元素类型
// props: 元素属性
// children: 子元素
function createElement(type, props, ...children) {return {type,props: {...props,children: children.map((child) => {return typeof child === "string" ? createTextNode(child) : child;}),},};
}// 渲染函数:将React元素渲染到容器中
function render(el, container) {nextWorkOfUnit = {dom: container,props: {children: [el],},};
}// 下一个工作单元
let nextWorkOfUnit = null;// 工作循环:利用浏览器空闲时间处理任务
function workLoop(deadline) {let shouldYield = false;while (!shouldYield && nextWorkOfUnit) {nextWorkOfUnit = performWorkOfUnit(nextWorkOfUnit);// 当剩余时间小于1ms时,让出主线程shouldYield = deadline.timeRemaining() < 1;}requestIdleCallback(workLoop);
}// 根据类型创建DOM节点
function createDom(type) {return type === "TEXT_ELEMENT"? document.createTextNode(""): document.createElement(type);
}// 更新DOM节点的属性
function updateProps(dom, props) {Object.keys(props).forEach((key) => {if (key !== "children") {dom[key] = props[key];}});
}// 初始化fiber节点的子节点
// 构建fiber树的链表结构:child(第一个子节点)和sibling(兄弟节点)
function initChildren(fiber) {const children = fiber.props.children;let prevChild = null;children.forEach((child, index) => {const newFiber = {type: child.type,props: child.props,child: null,parent: fiber,sibling: null,dom: null,};if (index === 0) {fiber.child = newFiber;} else {prevChild.sibling = newFiber;}prevChild = newFiber;});
}// 处理工作单元
// 主要完成三件事:
// 1. 创建DOM节点
// 2. 处理props
// 3. 构建fiber树
// 4. 返回下一个工作单元
function performWorkOfUnit(fiber) {// 1. 创建DOM节点,保证一次只处理一个fiber节点(任务分片机制)if (!fiber.dom) {const dom = (fiber.dom = createDom(fiber.type));// 将DOM节点添加到父节点fiber.parent.dom.append(dom);// 2. 处理propsupdateProps(dom, fiber.props);}// 3. 构建fiber树initChildren(fiber)// 4. 返回下一个要执行的任务// 遍历顺序:先子节点,然后兄弟节点,最后回到父节点的兄弟节点if (fiber.child) {return fiber.child;}if (fiber.sibling) {return fiber.sibling;}return fiber.parent?.sibling;
}// 启动工作循环
requestIdleCallback(workLoop);// React对象
const React = {render,createElement,
};export default React;

相关文章:

不只是mini-react第二节:实现最简fiber

省流|总结 首先&#xff0c;我们编写JSX文件&#xff0c;并通过Babel等转换工具将其转化为createElement()函数的调用&#xff0c;最终生成虚拟 DOM&#xff08;Vdom&#xff09;格式。举个例子&#xff1a; // 原始 JSX const App <div>hi-mini-react</div>;//…...

C++实现设计模式---命令模式 (Command)

命令模式 (Command) 命令模式 是一种行为型设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使得可以用不同的请求对客户端进行参数化、对请求排队或记录日志&#xff0c;以及支持可撤销的操作。 意图 将操作的调用者与接收者分离&#xff0c;通过将请求封装为独…...

设计模式的艺术-享元模式

结构性模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解享元模式 当一个软件系统在运行时产生的对象数量太多&#xff0c;将导致运行代价过高&#xff0c;带来系统性能下降等问题。 在享元模式中&#xff0c;存储这些共享实例对象的地方称为享元池&…...

Linux的权限和一些shell原理

目录 shell的原理 Linux权限 sudo命令提权 权限 文件的属性 ⽂件类型&#xff1a; 基本权限&#xff1a; chmod改权限 umask chown 该拥有者 chgrp 改所属组 最后&#xff1a; 目录权限 粘滞位 shell的原理 我们广义上的Linux系统 Linux内核Linux外壳 Linux严格…...

【Postgres_Python】使用python脚本批量创建和导入多个PG数据库

之前批量创建和导入数据库分为2个python脚本进行&#xff0c;现整合优化代码合并为一个python脚本&#xff0c;可同步实现数据库的创建和数据导入。之前的文章链接&#xff1a; 【Postgres_Python】使用python脚本批量创建PG数据库 【Postgres_Python】使用python脚本将多个.S…...

Ubuntu安装GitLab

在 Ubuntu 上安装 GitLab 的步骤如下。这里以 GitLab Community Edition&#xff08;CE&#xff09;为例&#xff1a; 前提条件 确保你的 Ubuntu 系统是 20.04 或更高版本。确保你的系统满足 GitLab 的硬件要求。 步骤 更新系统包&#xff1a; sudo apt update sudo apt upg…...

网络知识小科普--5

81、什么是组播路由? 组播路由是一种有针对性的广播形式&#xff0c;将消息发送到所选择的用户组&#xff0c;而不是将其发送到子网上的所有用户。 82、加密在网络上的重要性是什么? 加密是将信息转换成用户不可读的代码的过程。然后使用秘密密钥或密码将其翻译或解密回其…...

JavaScript学习记录23

第十一节 JSON对象 1. JSON 格式 JSON 格式&#xff08;JavaScript Object Notation 的缩写&#xff09;是一种用于数据交换的文本格式&#xff0c;2001年由 Douglas Crockford 提出&#xff0c;目的是取代繁琐笨重的 XML 格式。 相比 XML 格式&#xff0c;JSON 格式有两个显…...

VScode 开发 Springboot 程序

1. 通过maven创建springboot程序 输入 mvn archetype:generate 选择模板&#xff0c;一般默认选择为第 7 种方式&#xff1b; 选择之后&#xff0c;一般要你填写如下内容&#xff1a; groupId: 组织名称&#xff1b;artifactId: 项目名称&#xff1b;version: 版本&#xff0…...

.git/hooks/post-merge 文件的作用

.git/hooks/post-merge 文件是 Git 版本控制系统中的一个钩子&#xff08;hook&#xff09;脚本&#xff0c;其作用是在合并&#xff08;merge&#xff09;操作完成后自动执行一些特定的操作。以下是关于 .git/hooks/post-merge 文件作用的详细解释&#xff1a; 作用 自动化任…...

Kafak 单例生产者实现-C#操作

前面写了一篇入门操作的文章,因为工作需要,简单修改了下如何实现单例生产者。 Kafka入门-C#操作_c# kafka-CSDN博客文章浏览阅读1.6k次,点赞20次,收藏9次。2).报错:“kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state…...

Cursor开发前端的详细过程

以下是使用 Cursor 开发前端的详细过程&#xff1a; 一、创建项目 打开 Cursor 并新建项目&#xff1a; 启动 Cursor 编辑器。点击 “File” 菜单&#xff0c;选择 “New Project”。在弹出的对话框中&#xff0c;输入项目名称&#xff0c;如 “MyFrontendProject”&#xff0…...

基于微信小程序的移动学习平台的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

atheris从安装到fuzz输入输出解读

1. 引入 模糊测试是一种自动化的软件测试技术&#xff0c;它通过自动生成大量随机数据作为输入来测试程序&#xff0c;以发现潜在的错误、漏洞或崩溃。atheris是一个专门用于CPython&#xff08;Python的C语言实现&#xff09;的模糊测试框架。 2. 安装atheris 参考1&#x…...

「 机器人 」系统辨识实验浅谈

前言 系统辨识实验是一种通过实验和数据分析的方法,用于建立物理系统的数学模型的技术。系统辨识是控制工程和系统科学中的重要环节,尤其是在模型未知或复杂的情况下。以下是系统辨识实验的详细介绍: 1. 系统辨识实验的目的 1.1 建模 为动态系统(如机械系统、电气系统或生…...

基于Flask的哔哩哔哩评论数据可视化分析系统的设计与实现

【Flask】基于Flask的哔哩哔哩评论数据可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统可以搜索查看作者、播放量、评论等相关信息&#xff0c;并将相关的分析…...

[央企大赛 2025] pwn

拿到堆附件&#xff0c;不清楚哪个是密码哪个是pwn&#xff0c;找到两个pwn&#xff0c;一个RSA密码相对简单&#xff08;已知e,d,N,直接用N解出k((ed-1)//phi_N(ed-1)//N^2),然后求pq&#xff0c;而phi_N正好是pq的2次方程&#xff09;。就只复现了两个pwn&#xff0c;感觉还有…...

C语言初阶--折半查找算法

目录 练习1&#xff1a;在一个有序数组中查找具体的某个数字n 练习2&#xff1a;编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 练习3&#xff1a;简单编写代码实现&#xff0c;模拟用户登录情景&#xff0c;并且只能登录三次 练习4&#xff1a;猜数字…...

Python!从0开始学爬虫:(一)HTTP协议 及 请求与响应

前言 爬虫需要基础知识&#xff0c;HTTP协议只是个开始&#xff0c;除此之外还有很多&#xff0c;我们慢慢来记录。 今天的HTTP协议&#xff0c;会有助于我们更好的了解网络。 一、什么是HTTP协议 &#xff08;1&#xff09;定义 HTTP&#xff08;超文本传输协议&#xff…...

[ Spring ] Spring Cloud Gateway 2025 Comprehensive Overview

文章目录 Spring Gateway ArchitectureProject Level DependencyService CenterService ProviderGateway ServiceLaunch All Service Spring Gateway Architecture Service Center : register and find service providerService Provider : programs that provide actual serv…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

rm视觉学习1-自瞄部分

首先先感谢中南大学的开源&#xff0c;提供了很全面的思路&#xff0c;减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接&#xff1a;https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架&#xff1a; 代码框架结构&#xff1a;readme有…...

职坐标物联网全栈开发全流程解析

物联网全栈开发涵盖从物理设备到上层应用的完整技术链路&#xff0c;其核心流程可归纳为四大模块&#xff1a;感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性&#xff0c;例如传感器选型需平衡精度与…...

【R语言编程——数据调用】

这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中&#xff0c;有多个库支持调用内置数据集或外部数据&#xff0c;包括studentdata等教学或示例数据集。以下是常见的库和方法&#xff1a; 可用库及数据集 openintro库 该库包含多个教学数据集&a…...

7种分类数据编码技术详解:从原理到实战

在数据分析和机器学习领域&#xff0c;分类数据&#xff08;Categorical Data&#xff09;的处理是一个基础但至关重要的环节。分类数据指的是由有限数量的离散值组成的数据类型&#xff0c;如性别&#xff08;男/女&#xff09;、颜色&#xff08;红/绿/蓝&#xff09;或产品类…...