pandas-03-组合连接数据

news2024/9/28 11:20:24

采集的数据存储后通常会分为多个文件或数据库,如何将这些文件按需拼接,或按键进行连接十分重要。这节将介绍数据索引的复杂操作如分层索引,stack,unstack,seet_index,reset_index等帮助重构数据,数据的拼接如merge,join,concat,combine_first等帮助连接数据,以及数据透视表的使用。

目录

  • A. 分层索引
    • 1. 创建分层索引
      • A.1.1 Series分层索引
      • A.1.2 DataFrame分层索引
      • A.1.3 直接创建多层索引再重用它
    • 2. 分层索引的引用与属性
      • A.2.1 对分层Series的引用
      • A.2.1 分层DataFrame的层数判断
    • 3. 多层行列索引之间的转换
      • A.3.1 Series.unstack() DataFrame.stack() 用法
      • A.3.2 DataFrame.set_index 与 DataFrame.reset_index
      • A.3.3 索引轴更换顺序与排序
    • 4. 分层计算统计量
  • B. 组合与合并数据
    • 1. pd.merge() pd.join()使用键连接数据
      • B.1.1 根据Df的列(键)合成数据
      • B.1.2 根据Df的索引列合成数据
      • B.1.3 合成的集合选择方式(how参数)
      • B.1.4 合成时不作为键但列名相同的列(suffixes参数)
      • B.1.5 pd.merge参数总结(其他参数)
      • B.1.6 使用pd.join简化按索引列合并
    • 2. pd.concat()按轴方向串联数据
    • 3. df.combine_first()实现有重复索引的选择性拼接
  • C. 数据透视表
    • C.1 df.pivot
    • C.2 pd.melt

A. 分层索引

1. 创建分层索引

A.1.1 Series分层索引

  • 在创建Series时,使用嵌套列表的方式指定它的索引,就会生成分层索引的Series数组
  • 可以使用S.index.names 对多层索引命名
  • S.index 是一个多层索引对象MultiIndex,它的每一个元素是一个元组
data = pd.Series(np.random.uniform(size=9),
                 index=[["a", "a", "a", "b", "b", "c", "c", "d", "d"],
                        [1, 2, 3, 1, 3, 1, 2, 2, 3]],
                )
data.index.names = ['word','num']
                

在这里插入图片描述

A.1.2 DataFrame分层索引

  • 在创建DataFrame时,指定它的行和列都是用嵌套列表,就会生成分层索引的Df
  • 可以对行和列的分层索引命名 Df.index.name=[ ] ,Df.columns.names=[ ]
frame = pd.DataFrame(np.arange(12).reshape((4, 3)),
                     index=[["a", "a", "b", "b"], [1, 2, 1, 2]],
                     columns=[["Ohio", "Ohio", "Colorado"],
                              ["Green", "Red", "Green"]])
frame.index.names = ["key1", "key2"]
frame.columns.names = ["state", "color"]                             

在这里插入图片描述
在这里插入图片描述

A.1.3 直接创建多层索引再重用它

除了在创建Series和DataFrame时,通过嵌套列别指定所层索引的形式,还可以直接生成所层索引MultiIndex,这样可以重复使用这个索引。

pd.MultiIndex.from_arrays([["Ohio", "Ohio", "Colorado"],
                              ["Green", "Red", "Green"]],
                              names=["state", "color"])

在这里插入图片描述

2. 分层索引的引用与属性

A.2.1 对分层Series的引用

A.3.1 可以看出Series分层索引与Df之间可以相互转换,所以使用对Df的引用方法可以实现对Series的引用。下面实例中data是前文的data
在这里插入图片描述

A.2.1 分层DataFrame的层数判断

Df.index.nlevels
Df.columns.nelvels

在这里插入图片描述

3. 多层行列索引之间的转换

A.3.1 Series.unstack() DataFrame.stack() 用法

每一次使用unstack相当于把行中最内层的索引放到列最内层中,比如原来行有a,b,c和1,2,3这两种索引,使用一次unstack会把内层的1,2,3这个索引放到行上,形成Df。
在这里插入图片描述
对于三层的行索引可以更清晰的看出,比如下面这个数据有a,b,c ;1,2,3;x,y,z三种,每一次使用unstack会把最内层的行索引放到最内层的列索引中。直到最后索引顺序变为x,y,z;1,2,3;a,b,c。

data_ = pd.Series(np.random.uniform(size=9),
                 index=[["a", "a", "a", "b", "b", "c", "c", "d", "d"],
                        [1, 2, 3, 1, 3, 1, 2, 2, 3],['x','y','x','y','x','y','x','y','x']]
                )
data_.index.nlevels
data_.unstack()
data_.unstack().unstack()
data_.unstack().unstack().unstack()

在这里插入图片描述

  • 可以通过level指定要挪动的索引,可以使用整数位置或者索引标签名称,但是默认还是会放到列的最内侧。
    df.unstack(level=0)
    df.unstack(level=‘name1’)
  • 使用.stack方法后会默认将含有空值的行删除,使用dropna=Falese参数可以保留空值。
data = pd.DataFrame(np.arange(6).reshape((2, 3)),
                    index=pd.Index(["Ohio", "Colorado"], name="state"),
                    columns=pd.Index(["one", "two", "three"],
                    name="number"))
result.unstack(level=0)
result.unstack(level="state")

在这里插入图片描述

s1 = pd.Series([0, 1, 2, 3], index=["a", "b", "c", "d"], dtype="Int64")
s2 = pd.Series([4, 5, 6], index=["c", "d", "e"], dtype="Int64")
data2 = pd.concat([s1, s2], keys=["one", "two"])

data2.unstack()
data2.unstack().stack(dropna=False)

在这里插入图片描述

df = pd.DataFrame({"left": result, "right": result + 5},
                  columns=pd.Index(["left", "right"], name="side"))
df
df.unstack(level="state")

df.unstack(level="state").stack(level="side")

在这里插入图片描述

A.3.2 DataFrame.set_index 与 DataFrame.reset_index

  • 可以 选择把Df的某列或某几列作为多层索引Df.set_index([‘col1’,‘col2’])
  • 默认变成索引的列不再出现在列中,但是使用drop=False可以让成为索引的列仍然出现在行中
  • 将所有的索引都移动到列中Df.reset_index
frame = pd.DataFrame({"a": range(7), "b": range(7, 0, -1),
                      "c": ["one", "one", "one", "two", "two",
                            "two", "two"],
                      "d": [0, 1, 2, 0, 1, 2, 3]})
frame2 = frame.set_index(["c", "d"])
frame.set_index(["c", "d"], drop=False)
frame2.reset_index()                     

在这里插入图片描述

A.3.3 索引轴更换顺序与排序

Df.swaplevel('key1,key2']
Df.sort_index(level=1)
Df.sawplevel(0,1).sort_index(level=0)

在这里插入图片描述

4. 分层计算统计量

使用groupby

frame.groupby(level="key2").sum()
frame.groupby(level="color", axis="columns").sum()

在这里插入图片描述

B. 组合与合并数据

1. pd.merge() pd.join()使用键连接数据

将两个Df对象按照某列的对应关系,或者索引之间的对应关系合并成一张表,在关系型数据库中这种操作很常见。在pandas中使用merge或者join函数完成这种合并连接。下面详细介绍pd.merge()的详细用法。假设待连接的两个数组分别是df1,df2。

B.1.1 根据Df的列(键)合成数据

  • pd.merge(df1,df2) 不指定键名,将默认使用重复的列作为键连接两个数组
  • pd.merge(df1,df2,on=‘key’) ;on 参数需要是两个数组共有的列名,将以它为键进行合并
  • pd.merge(df1,df2,left_on=‘lkey’,right_on=‘rkey’) ;用于两个数组分别以不同的列名作为键合并
  • 也可以指定多个列为连接的键pd.merge(left, right, on=[“key1”, “key2”])
#data
df1 = pd.DataFrame({"key": ["b", "b", "a", "c", "a", "a", "b"],
                    "data1": pd.Series(range(7), dtype="Int64")})
df2 = pd.DataFrame({"key": ["a", "b", "d"],
                    "data2": pd.Series(range(3), dtype="Int64")})

#pd.merge
pd.merge(df1, df2)
pd.merge(df1, df2, on="key")

#left_on,right_on
df3 = pd.DataFrame({"lkey": ["b", "b", "a", "c", "a", "a", "b"],
                    "data1": pd.Series(range(7), dtype="Int64")})
df4 = pd.DataFrame({"rkey": ["a", "b", "d"],
                    "data2": pd.Series(range(3), dtype="Int64")})
pd.merge(df3, df4, left_on="lkey", right_on="rkey")                    

#指定多个键,默认将取两个键都对应的在两个数组间的交集
left = pd.DataFrame({"key1": ["foo", "foo", "bar"],
                     "key2": ["one", "two", "one"],
                     "lval": pd.Series([1, 2, 3], dtype='Int64')})
right = pd.DataFrame({"key1": ["foo", "foo", "bar", "bar"],
                      "key2": ["one", "one", "one", "two"],
                      "rval": pd.Series([4, 5, 6, 7], dtype='Int64')})
pd.merge(left, right, on=["key1", "key2"], how="outer")

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

B.1.2 根据Df的索引列合成数据

某个数组待合并的键并不出现在列中,而是以索引的方式出现在数组中,也可以实现索引与列之间的连接。

  • right_index = True 使用右侧数组的索引为键值
  • left_index = True 使用左侧数组的索引为键值
  • 若一侧指定了多个列为键值,那么另一侧需要有对应的多层索引,也就是A.部分提到的知识。
#data
left1 = pd.DataFrame({"key": ["a", "b", "a", "a", "b", "c"],
                      "value": pd.Series(range(6), dtype="Int64")})
right1 = pd.DataFrame({"group_val": [3.5, 7]}, index=["a", "b"])

#这里左侧使用键,右侧使用索引
pd.merge(left1, right1, left_on="key", right_index=True)

在这里插入图片描述

在这里插入图片描述

B.1.3 合成的集合选择方式(how参数)

两个合并的数组,键值可能不完全相同,通过how参数可以指定结果使用哪种方式对键值进行选择

  • inner 使用两个数组共有的键值作为最终结果,即取交集(默认方式)
  • left 使用左侧数组的键值
  • right 使用右侧数组的键值
  • outer 使用二者相结合的键值,即取并集
    在这里插入图片描述
pd.merge(df1, df2,how='outer')
pd.merge(df1, df2,how='outer')
pd.merge(df1, df2,how='right')

在这里插入图片描述
在这里插入图片描述

B.1.4 合成时不作为键但列名相同的列(suffixes参数)

当不以重名的列作为键进行合并时,合并后为区分两个列会自动添加一个后缀
也可以使用suffixes参数手动指定添加的后缀 suffixes(‘_left’,‘_right’)

pd.merge(left, right, on="key1", suffixes=("_left", "_right"))

在这里插入图片描述

B.1.5 pd.merge参数总结(其他参数)

其他参数如下表,等待读者参考官方文档自行探索。
在这里插入图片描述

B.1.6 使用pd.join简化按索引列合并

上述pd.merge()方法在使用索引为键值的情况,参数略微有一些繁琐。而pd.join()方法 可以简化。

  • 当df1 和 df2 都以索引作为键进行合并时使用 df1.join(df2) 默认的连接方式为左连接(相当于how=left)
  • 当df1使用列 与df2的索引 作为键进行合并时,df1.join(df2,on=‘key’)
  • 可以使用join向df1插入多个数组 df1.join([df2,df3]) 默认的连接方式也是左连接
# data
left1 = pd.DataFrame({"key": ["a", "b", "a", "a", "b", "c"],
                      "value": pd.Series(range(6), dtype="Int64")})
right1 = pd.DataFrame({"group_val": [3.5, 7]}, index=["a", "b"])
left2 = pd.DataFrame([[1., 2.], [3., 4.], [5., 6.]],
                     index=["a", "c", "e"],
                     columns=["Ohio", "Nevada"]).astype("Int64")
right2 = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [13, 14]],
                      index=["b", "c", "d", "e"],
                      columns=["Missouri", "Alabama"]).astype("Int64")
another = pd.DataFrame([[7., 8.], [9., 10.], [11., 12.], [16., 17.]],
                       index=["a", "c", "e", "f"],
                       columns=["New York", "Oregon"])                      
                      

# df1.join(df2)
left2.join(right2)

# df1.join(df2,how='outer')
left2.join(right2, how="outer")

# df1.join(df,on='key') key是df1的键
left1.join(right1, on="key")

# df1.join([df2,df3]) 
left2.join([right2, another])
left2.join([right2, another], how="outer")

在这里插入图片描述
在这里插入图片描述

2. pd.concat()按轴方向串联数据

  • pd.concat()会按照指定轴的方向,将数组以及索引都连接起来。
  • pd.concat()第一个参数制定待连接的对象,可以是列表的形式pd.concat([df1,df2’])
  • 默认连接方向是向下(沿行),如果需要向右拼接(沿列)需要指定参数 axis=‘columns’
  • 默认是取待串联的数组各个索引的并集。如需要取交集,需要指定参数join=‘inner’
  • 可以对被拼接的轴增加一层索引,通过keys参数指示来自哪个是数组pd.concat([df1,df2,df3],keys=[‘1’,‘2’,‘3’])
  • pd.concat()第一个参数制定待连接的对象,也可以是字典的形式pd.concat({‘l1’:df1,‘l2’:df2})这里l1 l2 也会给被拼接轴增加一层索引,指示数据来自哪个数组。
  • names参数可以对形成的多层索引命名。
  • 默认生成的新数组索引时原数组的拼接(沿轴串联保留索引),若想重新生成索引,使用ignore_index=True
# data 三个数组索引没有交集
s1 = pd.Series([0, 1], index=["a", "b"], dtype="Int64")
s2 = pd.Series([2, 3, 4], index=["c", "d", "e"], dtype="Int64")
s3 = pd.Series([5, 6], index=["f", "g"], dtype="Int64")

# 默认横向拼接,默认取并集
pd.concat([s1, s2, s3])

#纵向拼接
pd.concat([s1, s2, s3], axis="columns")

#对于有重复的数据,取并集
s4 = pd.concat([s1, s3])
#取交集
pd.concat([s1, s4], axis="columns", join="inner")

#依据数据来源设置分层索引
result = pd.concat([s1, s1, s3], keys=["one", "two", "three"])

#data 两个Df
df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=["a", "b", "c"],
                   columns=["one", "two"])
df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=["a", "c"],
                   columns=["three", "four"])

#纵向拼接,按数据来源设置分层索引
pd.concat([df1, df2], axis="columns", keys=["level1", "level2"])
#也可以按字典方式设置分层索引并传入数据
pd.concat({"level1": df1, "level2": df2}, axis="columns")

#默认索引是将原来的拼接在一起但是也可以指定重新排雷索引
df1 = pd.DataFrame(np.random.standard_normal((3, 4)),
                   columns=["a", "b", "c", "d"])
df2 = pd.DataFrame(np.random.standard_normal((2, 3)),
                   columns=["b", "d", "a"])
pd.concat([df1, df2], ignore_index=True)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. df.combine_first()实现有重复索引的选择性拼接

pd.merge可以实现将重复索引作为键值,连接其他列
pd.concat 可以实现将重复索但值不同会合成不同的行
而df.combine_first()可以实现对于重复色索引,但是值不同,选择其中某个数组的值行层新的列。
a.combine_first(b)实现的功能类似于np.where(pd.sina(a),b,a) ,也就是说当a为空值时,选择b的值填入,当a为非空时选择a的值。
对于Df来说,就是对每一列进行上述操作。

# data
a = pd.Series([np.nan, 2.5, 0.0, 3.5, 4.5, np.nan],
              index=["f", "e", "d", "c", "b", "a"])
b = pd.Series([0., np.nan, 2., np.nan, np.nan, 5.],
              index=["a", "b", "c", "d", "e", "f"])

#以下两个命令类似
np.where(pd.isna(a), b, a)
a.combine_first(b)

#data
df1 = pd.DataFrame({"a": [1., np.nan, 5., np.nan],
                    "b": [np.nan, 2., np.nan, 6.],
                    "c": range(2, 18, 4)})
df2 = pd.DataFrame({"a": [5., 4., np.nan, 3., 7.],
                    "b": [np.nan, 3., 4., 6., 8.]})
df1.combine_first(df2)                    

在这里插入图片描述

C. 数据透视表

C.1 df.pivot

假设现在数据的解构如下表,item列代表不同的键(可以转换成很多列),value代表不同的值
在这里插入图片描述
现要将其转换为常规Df的新式,即每一列都是一种数据使用Df.pivot(index= ,columns=‘item’,value=)
如下图:
在这里插入图片描述

  • 达到的效果和把item列移动到列索引类似。
    在这里插入图片描述

C.2 pd.melt

pd.melt 与df.pivot达到的效果相反。
pd.melt(df,id_vars=‘key’)会将Df的各列合并成一列,其中id_vars可以不指定
在这里插入图片描述
使用pivot复原
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/934016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pandas数据分析——groupby得到分组后的数据

groupbyagg分组聚合对数据字段进行合并拼接 Pandas怎样实现groupby聚合后字符串列的合并(四十) groupby得到分组后的数据 pandas—groupby如何得到分组里的数据 date_range补齐缺失日期 在处理时间序列的数据中,有时候会遇到有些日期的数…

python编程环境使用技巧3-程序打包pyinstaller

前言 在Python中,打包指的是将Python代码和相关资源(如配置文件、图像等)整合到一个可执行的文件或安装包中,以便于在其他环境中使用。 下面是使用pyinstaller进行打包的简要步骤: 1-安装pyinstaller:在命…

python之OCR文字识别

将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR)。可以实现OCR 的底层库并不多,目前很多库都是使用共同的几个底层OCR 库,或者是在上面进行定制。 方法一: 使用easyocr模块 …

Redis三种特殊数据类型

Redis三种特殊数据类型 geospatial 地理位置 Redis 地理空间数据类型简介 Redis 地理空间索引允许您存储坐标并搜索它们。 此数据结构可用于查找给定半径或边界框内的邻近点。 基本命令 GEOADD 将位置添加到给定的地理空间索引(请注意,使用此命令&a…

为什么物联网和端点安全需要细化

组织和个人越来越关心:物联网 ( IoT ) 的激增以及这些设备创建的无数端点。预计到 2025 年将有 750 亿个物联网设备投入使用,确保这些设备的安全已经至关重要。 2019 年生产的设备预期寿命只有五年,现在存在大量制造商在生产过程中无法预见的…

ChatGPT在高等教育中的应用利弊探讨

​人工智能在教育领域的应用日益广泛。2022年11月OpenAI开发的聊天机器人ChatGPT在全球范围内流传开来,其中用户数量最多的国家是美国(15.22%)。由于ChatGPT应用广泛,具有类似人类回答问题的能力,它正在成为许多学生和教育工作者的可信赖伙伴…

python编程环境使用技巧-任务1-pip包管理工具

概要 任务1-pip包管理工具 pip是Python的包管理工具,它用于安装、升级和管理Python的第三方库以及它们的依赖关系。 在命令提示符或终端窗口中,可以使用以下常用的pip命令: 安装包:pip install package_name。它会自动下载并安…

开源在大数据和分析中的角色

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

STM32开发 | 移远4G-Cat.1模组EC200N-CN开发

一、硬件说明 1、引脚分配图 文章来源地址https://www.yii666.com/blog/326636.html文章来源地址:https://www.yii666.com/blog/326636.html 2、常用引脚说明 模块输入电源 引脚名描述VBAT_BB模块基带电源(Vnom 3.8 V)VBAT_RF模块射频电源&#xff0…

SQL Server软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 SQL Server是一种关系型数据库管理系统,由美国微软公司开发。它被设计用于存储、管理和查询数据,被广泛应用于企业级应用、数据仓库和电子商务等场景。 以下是SQL Server软件的主要特点和功能&#xff1…

春秋云镜 CVE-2022-0788

春秋云镜 CVE-2022-0788 wordpress插件 WP Fundraising Donation and Crowdfunding Platform < 1.5.0 SQLI 靶标介绍 wordpress插件 WP Fundraising Donation and Crowdfunding Platform < 1.5.0 的其中一个REST路由在SQL语句使用时没有对参数进行过滤&#xff0c;导致…

Visual Assist 10.9.2500 Crack

General Release Build 2023.3 (2491) Requires active software maintenance through general release date: 2023.05.24 NEW Added parser support for “is” operators in C#. UPDATE Code inspection engine updated to LLVM/Clang version 16. Summary: VA 2023.3 is …

学信息系统项目管理师第4版系列02_法律法规

1. 信息安全的法律体系可分为四个层面 1.1. 一般性法律法规&#xff0c;如宪法、国家安全法&#xff0c;国家秘密法 1.2. 规范和惩罚信息网络犯罪的法律&#xff0c;如刑法、《全国人大常委会关于维护互联网安全的决定》等 1.3. 直接针对信息安全的特别规定&#xff0c;如《…

兵力集中更容易进攻获胜

我兵力集中&#xff0c;敌兵力分散&#xff0c;进攻可胜 【安志强趣讲《孙子兵法》第21讲】 【原文】 进而不可御者&#xff0c;冲其虚也&#xff1b;退而不可追者&#xff0c;速而不可及也。 【趣讲白话】 进攻时&#xff0c;敌人无法抵御&#xff0c;那是攻击了敌人空虚的地方…

Visual Studio软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Visual Studio是微软公司开发的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;广泛应用于Windows平台上的应用程序和Web应用程序的开发。以下是Visual Studio软件的主要特点和功能&#xff1a; 集成开发环境&#x…

如何使用基于SSH密钥的身份验证来实现安全地远程登录?

SSH密钥身份验证的优势SSH密钥身份验证的原理设置基于SSH密钥的身份验证感谢 &#x1f496; hello大家好&#x1f60a; 当涉及远程访问和安全通信时&#xff0c;SSH&#xff08;Secure Shell&#xff09;密钥身份验证成为一种强大的工具。SSH密钥身份验证通过使用公钥和私钥的组…

Cocos独立游戏开发框架中的事件管理器

引言 本系列是《8年主程手把手打造Cocos独立游戏开发框架》&#xff0c;欢迎大家关注分享收藏订阅。在独立游戏开发中&#xff0c;事件管理器是一个不可或缺的组件。它为开发者提供了一种灵活的方式来处理游戏内部各种状态变化和用户交互&#xff0c;实现模块之间的解耦和通信…

BDCC - 闲聊数据仓库的架构

文章目录 典型数据仓库架构图数据仓库ETL vs ELTETLELT区别联系 数据仓库分层&#xff08;1&#xff09;数据仓库ODS层&#xff08;2&#xff09;数据仓库CDM层DWD数据明细层DWS数据汇总层 &#xff08;3&#xff09;数据仓库ADS层 典型数据仓库架构图 按自下而上的顺序&#x…

Linux系统---信号

文章目录 信号是什么信号的产生信号的系统调用接口软件条件产生信号硬件异常产生信号阻塞信号信号处理 一、信号是什么 1.生活中的信号 你在网上买了很多件商品&#xff0c;再等待不同商品快递的到来。但即便快递没有到来&#xff0c;你也知道快递来临时&#xff0c; 你该怎么…

基于Java+SpringBoot+Vue前后端分离景区民宿预约系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…