在Excel中编写Python代码:Anaconda Code(1)REF函数的基本介绍

快乐小子新
快乐小子新 Lv.2 潜力创作者

Lv.2潜力创作者

一、概述

https://www.anaconda.com/docs/tools/excel/code

Anaconda Code 是 Anaconda Toolbox Excel 加载项的核心功能模块,当前处于 Beta 阶段。它允许用户直接在 Excel 工作表中编写并运行 Python 或 R 代码,代码在本地 WASM 环境中执行(基于 Pyodide 或 WebR 引擎),数据与代码完全保留在工作簿内,不依赖云端服务传送。Anaconda Code 独立于 Microsoft 的 Python in Excel 功能运行,为用户提供了更灵活的环境控制能力,包括自定义包管理(支持 PyPI、PyScript app 和 .whl 文件三种安装源)、Pyodide 或 WebR 版本切换、单元格链接模式选择、代码输出模式设定等高级特性。

用户通过 Home 选项卡中的 Create Code Cell 按钮创建代码单元格,选择 Python 或 R 语言,设定默认的链接模式(孤立或链接)与输出模式(Excel Values 或 Code Object)后即可开始编码。代码编辑完成后点击 Run 执行,单元格会显示最后一行表达式的返回值,若代码没有返回值(如只定义了函数),则显示 </> NoneType。每次重新运行时,改动会自动保存。环境的配置管理通过 Environment 选项卡完成,包含 Pyodide 或 WebR 版本的切换、软件包的检索新增与移除等操作。Anaconda Code 还提供单元格复制、删除等辅助功能,并支持编辑已创建的代码。

二、REF 函数:Excel 与 Python 运行时的桥梁

REF 函数是 Anaconda Code 中连接 Excel 工作表与 Python 运行时的核心机制。当用户通过 UI 点击 REF 按钮并选择一个单元格区域后,Anaconda Code 会在代码编辑器中自动生成一条形如 REF("B3:C44") 的函数调用,返回一个列表的列表(list of lists),其中外部列表的每个元素对应工作表的一行,内部列表的每个元素对应该行的单元格值。REF 还可用于在孤立模式的不同代码单元格之间建立引用,例如 REF("B2") 可读取 B2 代码单元格的输出对象,且对被引用单元格的修改会自动触发引用单元格的重算,但反过来则不会,这是孤立模式下精心设计的定向计算模型。

这种列表嵌套列表是 Excel 二维表格在 Python 中的最直接映射,但裸的嵌套结构在复杂分析中不够直观。Anaconda Code 在 Imports and Definitions 选项卡的 # Define 区域预置了四个转换函数(is_listlike、to_df、to_array、to_list),用于将 REF 返回值转换为更高级的数据结构,对所有代码单元格全局可见。

三、预置工具函数

3.1 is_listlike(x) —— 类型判定基础设施

def is_listlike(x) -> bool:
    return hasattr(x, '__len__') and type(x) not in {str, bytes}

此函数是一个辅助性的类型判定工具,用于判断一个对象是否为类列表结构。判断逻辑包含两个条件:一是使用 hasattr(x, '__len__') 检查对象是否实现了 __len__ 方法,排除了整数、浮点数、None 等标量类型;二是通过 type(x) not in {str, bytes} 显式排除字符串和字节串,因为 str 和 bytes 虽然也有 __len__,但在语义上应被视为原子值而非可遍历的容器。这是 Python 序列类型处理中经典的边界条件,在 Python 的 collections.abc 模块中同样有类似设计。

该函数的精妙在于对 Python 鸭子类型的灵活运用——不要求对象必须是 list、tuple 等具体类型,只要实现了长度接口且不是字符串,就视为类列表对象。该函数被 to_df、to_array、to_list 三个核心函数内部调用,判断输入数据的维度结构,是整组工具函数的基础依赖。

3.2 to_df(data) —— 一键构建 pandas DataFrame

def to_df(data) -> pd.DataFrame:
    if isinstance(data, pd.DataFrame):
        return data
    if hasattr(data, '__len__') and len(data) > 0 and is_listlike(data[0]):
        return pd.DataFrame(data[1:], columns=data[0])
    raise TypeError('Expected list of lists')

该函数将 REF 返回的列表嵌套列表转换为 pandas DataFrame,处理逻辑包含三层分支:

  • 幂等性短路:若输入已经是 DataFrame,直接返回,避免重复转换造成的性能损耗,这在管道式链式调用中尤为重要。

  • 标准转换路径:假设首行为列名,剩余部分为数据行,调用 pd.DataFrame(data[1:], columns=data[0]) 构造。这是 Excel 用户最自然的语义,无需额外参数配置。

  • 异常处理:输入为空或格式不符时抛出明确的 TypeError。

典型用法为 df = to_df(REF("A1:F100"))。官方文档还注明用户可在 Imports and Definitions 中按需修改 to_df 的默认行为。

3.3 to_array(data) —— 数值计算的核心入口

def to_array(data) -> np.ndarray:
    if isinstance(data, np.ndarray):
        return data
    return np.array(data)

该函数将 REF 数据转换为 NumPy 多维数组,是纯数值计算和矩阵运算场景的首选工具。幂等性检查后直接通过 np.array(data) 转换。与 to_df 不同,to_array 不假设首行为表头,整个区域全部作为数值数据。官方文档明确标注类型一致性要求,若存在混合类型会导致 dtype 提升为 object 或字符串。典型用法 arr = to_array(REF("B3:C44")),适用于线性代数、统计建模、机器学习特征矩阵构建等 NumPy 原生计算场景。

3.4 to_list(data) —— 智能一维化降维

def to_list(data) -> list:
    if not is_listlike(data):
        return [data]
    if len(data) == 0 or not is_listlike(data[0]):
        return list(data)
    if len(data) == 1:
        return list(data[0])
    elif len(data[0]) == 1:
        return [x[0] for x in data]
    else:
        raise TypeError(f"data must be 1xn or nx1, not {len(data)}x{len(data[0])}")

to_list 是三者中分支最完整的函数,专门处理从二维向一维的降维转换,覆盖五种情况:标量输入的包裹处理、已一维列表的直通转换、宽数据的横向展平、长数据的纵向提取、以及非标二维数据的类型错误抛出。尤其值得注意的错误信息中精确注明了数据维度的 {len(data)}x{len(data[0])},极大降低了排查成本。

该函数对 Excel 单元格引用的形态做了精细适配:Excel 中单行选择表现为 [[g1,h1,i1,j1]],单列选择表现为 [[g1],[g2],...,[g55]],to_list 能自动识别两种形态并正确展平,无需用户手动判断方向,体现了良好的用户体验设计。

四、代码初始化体系

Imports and Definitions 选项卡相当于全局初始化脚本,类比 Jupyter Notebook 的第一个单元格。结构分为两个区域:# Add imports 区域放置所有 import 语句,默认模板已包含 import mathimport numpy as npimport pandas as pd;# Define 区域放置自定义类、函数和变量,包含上述四个预置工具函数的完整实现。所有代码在此定义后对所有代码单元格全局可见,无需重复导入。

对 R 语言用户,Anaconda Code 同样提供了对应的预置函数:to_dataframe() 转换为 data.frame 或 tibble、to_matrix() 转换为矩阵、to_colwise_list() 转换为列向量列表、is_list_of_lists() 检测数据结构,覆盖了与 Python 类似的功能场景。

五、UDF 与进阶功能

通过 @UDF 装饰器可将 Python 函数注册为 Excel 工作表函数,在单元格中以 =ANACONDA.FUNCTION_NAME() 调用调用返回值。支持 name 参数自定义函数名、nested=False 去掉 ANACONDA. 前缀、UDF.Range 类型注解声明二维输入参数以避免 #CALC! 错误。R 语言通过 UDF.register() 注册,支持 doc 参数添加函数文档。单元格链接模式支持孤立模式(变量隔离且 REF 显式引用)和链接模式(变量全共享且线性重算),配合 Excel Values 溢出显示和 Code Object 卡片视图两种输出模式,形成了完整灵活的数据分析工作流。

广东省
浏览 504
收藏
5
分享
5 +1
+1
全部评论