在 Microsoft Fabric 笔记本中使用 Copilot
Copilot for Fabric 数据工程功能有助于在笔记本中编写代码。 它使用笔记本上下文,包括附加的湖仓、可用的架构模式、表、文件、现有代码和运行时信息。
Important
数据工程和数据科学 Copilot 现已推出预览版。 当租户使用 Private Link 时,聊天窗格不起作用。 上下文感知针对 Lakehouses 进行优化;显式指定其他数据源。 生成的代码可以包含错误,包括不正确的库语法。 在批准执行之前查看它。 请参阅Copilot笔记本限制。
可以通过两种方式与Copilot进行交互:
- Copilot 聊天面板:以自然语言提问,并跨多个笔记本单元协同操作。 Copilot可以在维护工作流上下文的同时生成、编辑、运行、解释和验证代码。
- 单元格内的 Copilot:在单个代码单元格上方输入请求。 将此体验用于重点任务,例如生成代码或解释、修复、注释和优化现有代码。
使用Copilot聊天窗格
若要与 Copilot 开始覆盖整个笔记本的对话:
- 创建或打开笔记本。
- 附加一个湖屋以提供模式和数据上下文。
- 在笔记本功能区上,选择Copilot。 聊天窗格将在笔记本右侧打开。
- 在聊天框中输入提示,或选择建议的提示。
- 检查每个所请求的操作。 选择“允许”以允许Copilot添加或编辑代码并运行单元格,或选择“跳过”以拒绝操作。
- Copilot完成任务后,请查看结果和差异视图。 选择 “保留 ”以保留更改或 撤消 以还原更改。
Copilot可以在每个操作之前请求批准。 可以在聊天窗格的审批设置中更改此行为。 高风险操作(例如安装包或运行多个单元)始终需要批准。 有关详细信息,请参阅使用用于数据工程和数据科学的 Copilot 聊天窗格。
内嵌式 Copilot
内嵌式 Copilot 允许你直接在任何代码单元格上方与 Copilot 交互,而无需离开编辑上下文。 选择代码单元格上方显示的 Copilot 按钮以打开一个文本框,可在其中键入请求或使用斜杠命令。
可用的斜线命令有:
| Command | Description |
|---|---|
/explain |
提供单元格代码逻辑的纯语言说明。 |
/fix |
标识单元格中的错误并建议更正。 |
/comments |
自动向文档逻辑和数据更改添加代码注释。 |
/optimize |
建议改进性能和效率。 |
当你想优化特定单元格时,可以使用内嵌式 Copilot,例如,在共享笔记本之前了解转换的作用、修复语法错误或记录代码。 对于多步骤工作流或跨单元格任务,请改为切换到 Copilot 聊天窗格。
使用 Copilot 准备数据
在本示例中,您将使用用于 Fabric 数据工程的 Copilot 在湖仓中加载、转换和保存数据。 Contoso Health 是一个多专业医院网络,希望分析预计的人口数据,因为它考虑扩大其在欧盟(EU)的服务。 此示例使用欧盟统计处 欧洲统计局的人口预测数据集。
来源:EUROPOP2023按年龄、性别和预测类型划分的1月1日人口[proj_23np]。 源数据可以更改;下表具有说明性,并非固定的预期结果。
加载数据
在附加 lakehouse 的 PySpark (Python) 笔记本中开始,并将其设置为默认值。 Python文件 API 使用/lakehouse/default/,而 Spark 使用相对于该 lakehouse 的路径,例如Files/temp/proj_23np.tsv。 请参阅 使用笔记本加载数据。 打开Copilot聊天窗格,输入以下提示并提交:
Download the following file from this URL:
https://ec.europa.eu/eurostat/api/dissemination/sdmx/2.1/data/proj_23np$defaultview/?format=TSV
Write the file directly to /lakehouse/default/Files/temp/proj_23np.tsv. Create the parent folder if it doesn't exist yet.
当Copilot请求添加和运行代码单元的权限时,请查看请求的操作并选择“允许”。 Copilot生成可能与以下示例不同的代码:
#### ATTENTION: AI-generated code can include errors or operations you didn't intend. Review the code in this cell carefully before running it.
import urllib.request
import os
url = "https://ec.europa.eu/eurostat/api/dissemination/sdmx/2.1/data/proj_23np$defaultview/?format=TSV"
lakehouse_temp_folder = "/lakehouse/default/Files/temp"
os.makedirs(lakehouse_temp_folder, exist_ok=True)
file_path = os.path.join(lakehouse_temp_folder, "proj_23np.tsv")
urllib.request.urlretrieve(url, file_path)
print(f"File successfully written to {file_path}")
单元格运行后,该文件将显示在 lakehouse 的临时文件夹中。 查看结果,然后在“Copilot”窗格中选择“保留”。
在Copilot聊天框中,输入并提交以下提示:
Load the file 'Files/temp/proj_23np.tsv' into a spark dataframe.
The fields are separated with a tab.
Show the contents of the DataFrame using display method.
查看并允许所请求的操作。 生成的数据帧包含 TSV 文件的内容。 生成的代码可能类似于以下示例:
#### ATTENTION: AI-generated code can include errors or operations you didn't intend. Review the code in this cell carefully before running it.
# Load the file 'Files/temp/proj_23np.tsv' into a spark dataframe.
# The fields have been separated with a tab.
file_path = "Files/temp/proj_23np.tsv"
spark_df = spark.read.format("csv").option("delimiter", "\t").option("header", "true").load(file_path)
# Show the contents of the DataFrame using display method
display(spark_df)
输出结果可能的显示方式如下:
| freq,预测,性别,年龄,单位,地理\TIME_PERIOD | 2022 年 | 2023 年 | ... | 2100年 |
|---|---|---|---|---|
| A,BSL,F,TOTAL,PER,AT | 4553444 | 4619179 | ... | 4807661 |
| A,BSL,F,TOTAL,PER,BE | 5883978 | 5947528 | ... | 6331785 |
| A,BSL,F,TOTAL,PER,BG | 3527626 | 3605059 | ... | 2543673 |
| ... | ... | ... | ... | 5081250 |
| A,BSL,F,TOTAL,PER,CY | 463622 | 476907 | ... | 504781 |
转换数据
接下来,要求Copilot将合并的第一个字段拆分为单独的列,删除未使用的字段,标准化数据类型并筛选数据。 在聊天窗格中输入并提交以下提示:
Now transform this dataframe spark_df and split the first field 'freq,projection,sex,age,unit,geo\TIME_PERIOD' using a comma into 6 separate fields.
Keep only rows where freq is A, age is TOTAL, and unit is PER. Then remove the fields 'freq', 'age', 'unit'.
The fields 'projection', 'sex', 'geo' should be positioned first.
The 'projection' field contains codes that should be replaced with the following values:
_'BSL' -> 'Baseline projections'.
_'LFRT' -> 'Sensitivity test: lower fertility'.
_'LMRT' -> 'Sensitivity test: lower mortality'.
_'HMIGR' -> 'Sensitivity test: higher migration'.
_'LMIGR' -> 'Sensitivity test: lower migration'.
_'NMIGR' -> 'Sensitivity test: no migration'.
Filter the 'geo' field and remove values 'EA20' and 'EU27_2020' (these are not countries).
Filter the 'sex' field and remove 'T' (these are totals).
Strip spaces from all field names in the dataframe.
Convert the data type of all the year fields to integer.
Display (Render) the DataFrame.
查看并允许所请求的操作。 Copilot生成可能与以下示例不同的代码:
from pyspark.sql.functions import split, col
# Load the file 'Files/temp/proj_23np.tsv' into a spark dataframe.
file_path = "Files/temp/proj_23np.tsv"
spark_df = spark.read.format("csv").option("delimiter", "\t").option("header", "true").load(file_path)
# Split the first field 'freq,projection,sex,age,unit,geo\TIME_PERIOD' into 6 separate fields.
source_column = r'freq,projection,sex,age,unit,geo\TIME_PERIOD'
split_col = split(spark_df[source_column], ',')
spark_df = spark_df.withColumn('freq', split_col.getItem(0)) \
.withColumn('projection', split_col.getItem(1)) \
.withColumn('sex', split_col.getItem(2)) \
.withColumn('age', split_col.getItem(3)) \
.withColumn('unit', split_col.getItem(4)) \
.withColumn('geo', split_col.getItem(5))
# Keep annual population counts for all ages before removing these dimensions.
spark_df = spark_df.filter(
(col('freq') == 'A') & (col('age') == 'TOTAL') & (col('unit') == 'PER')
)
columns_to_drop = ['freq', 'age', 'unit', source_column]
spark_df = spark_df.drop(*columns_to_drop)
# Reorder the columns, placing 'projection', 'sex', 'geo' first
columns_order = ['projection', 'sex', 'geo'] + [column for column in spark_df.columns if column not in ['projection', 'sex', 'geo']]
spark_df = spark_df.select(*columns_order)
# Replace projection field codes with values
replace_map = {
'BSL': 'Baseline projections',
'LFRT': 'Sensitivity test: lower fertility',
'LMRT': 'Sensitivity test: lower mortality',
'HMIGR': 'Sensitivity test: higher migration',
'LMIGR': 'Sensitivity test: lower migration',
'NMIGR': 'Sensitivity test: no migration'
}
spark_df = spark_df.replace(replace_map, subset=['projection'])
# Filter the 'geo' field to remove values 'EA20' and 'EU27_2020'
spark_df = spark_df.filter(~spark_df['geo'].isin(['EA20', 'EU27_2020']))
# Filter the 'sex' field to remove 'T'
spark_df = spark_df.filter(spark_df['sex'] != 'T')
# Strip spaces from all field names
spark_df = spark_df.toDF(*(c.replace(' ', '') for c in spark_df.columns))
# Convert the data type of all the year fields to integer
for column in spark_df.columns:
if column.isnumeric():
spark_df = spark_df.withColumn(column, col(column).cast('int'))
# Display the DataFrame
display(spark_df)
输出结果可能的显示方式如下:
| 投影 | 性 | 地区 | 2022 年 | 2023 年 | ... | 2100年 |
|---|---|---|---|---|---|---|
| 基线预测 | 周五 | AT | 4553444 | 4619179 | ... | 4807661 |
| 基线预测 | 周五 | BE | 5883978 | 5947528 | ... | 6331785 |
| 基线预测 | 周五 | BG | 3527626 | 3605059 | ... | 2543673 |
| ... | ... | ... | ... | ... | ... | ... |
| 基线预测 | 周五 | LU | 320333 | 329401 | ... | 498954 |
保存数据
转换数据后,让 Copilot 将结果保存到湖仓中。 在聊天窗格中输入并提交以下提示:
Save the dataframe as a new table named 'Population' in the default lakehouse.
查看并允许所请求的操作。 Copilot生成可能与以下示例不同的代码:
#### ATTENTION: AI-generated code can include errors or operations you didn't intend. Review the code in this cell carefully before running it.
spark_df.write.format("delta").saveAsTable("Population")
这会创建新的 Delta 表,如果 Population 已存在,则失败。 在重复运行中,使用新的表名或在查看对现有数据的影响后显式选择适当的写入模式。
Validation
若要检查表是否已按预期保存,请展开湖仓中的 Tables 列表并查看其内容。 还可以使用Copilot 聊天窗格提出探索性问题。 Copilot 会给出解释,或请求获得添加并运行代码的权限。 例如:
What is the total baseline projected population for geo BE in 2050? Sum female and male values from the Population table, using only the Baseline projections scenario.
Copilot可以生成代码来筛选表并聚合女性和男性行。 仅使用筛选器时,会按性别返回单独的值,而不是总体总值。 在求和之前检查这两行是否存在并具有非 null 值:
# ATTENTION: AI-generated code can include errors or operations you didn't intend. Review the code in this cell carefully before running it.
from pyspark.sql.functions import col, sum as spark_sum
# Load the Population table into a Spark DataFrame
population_df = spark.read.table("Population")
# Filter for the projected population for geo BE in 2050
baseline_df = population_df.filter(
(col('geo') == 'BE')
& (col('projection') == 'Baseline projections')
& col('sex').isin('F', 'M')
)
rows = baseline_df.select('sex', '2050').collect()
if len(rows) != 2 or {row['sex'] for row in rows} != {'F', 'M'} or any(row['2050'] is None for row in rows):
raise ValueError("Expected one non-null 2050 value for each sex.")
result_df = baseline_df.agg(spark_sum(col('2050')).alias('Population2050'))
# Show the result
result_df.show()
应用Copilot最佳做法
- Copilot 目前在数据工程和数据科学场景中表现得最为出色,因此在这些领域中提出问题往往会产生更清晰的结果。
- 给 Copilot 提供数据资产的具体引用(如文件路径、表名称、列名)通常可以提高生成答案的针对性和实用性。
- 将数据加载为 DataFrame,或将数据集固定到湖仓中,可提供更丰富的上下文信息,从而实现更准确的分析和数据转换。
- 在运行代码之前,请保持启用审批提示并检查生成的代码。 撤消 还原笔记本编辑;不要将其视为已写入的数据的回滚或其他外部效果。