在这篇文章中,我分享了一些自深入研究新的 Excel 中的 Python 集成以来学到的一些有用技巧、诀窍和经验教训。您可以通过打开一个 Excel 工作簿并尝试复制代码和描述的行为(在适用时)来学习这些技巧。
注意:要复制这篇文章中的技巧,请 安装Excel 中的 Python试用版。
1. Excel 单元格输出和 print 函数
在 Excel 中的 Python 中找到自己的方向时,可以尝试的第一件事就是简单地编写您的第一个“Hello world“示例。如果您熟悉 Python 代码,您可能会尝试以下类似内容:
print(“Hello world, I am running Python in Excel”)
好吧,如果您将这行简单的代码输入 Python 单元格(使用 =PY)并运行它,则结果可能与您的预期不符。您不会看到 print 函数的字符串,而是会看到“None”。这是 Excel 的一项独特功能,因为 print 函数仅用于“诊断”和“日志记录”信息,而不是生成单元格输出。
但是,如果我们确实打开了“诊断”面板(如下所示),我们将能够看到我们的“Hello world”消息。
那么什么构成单元格的有效输出?每个 Python 单元格的执行以 read–eval–print 循环 (REPL) 方式工作,类似于在 Jupyter Notebook 单元格中运行 Python。单元格中将被评估的最后一个表达式(例如,Python 对象或已调用 Python 函数的返回值)将代表单元格的输出。
因此,要将我们的“Hello world”消息作为 Python 单元格中的内容查看,我们应该删除print 函数,只保留要评估的字符串对象(如下所示):
“Hello world, I am running Python in Excel”
2. Excel 值还是 Python 对象?
Python 单元格的输出可以是两种类型,可以在单元格旁边的下拉菜单中选择
默认情况下,Python 单元格的输出将设置为“Excel 值”。因此,单元格中代码返回的任何 Python 对象的值都将转换为等效的 Excel 输出。任何原始数据类型都将自动支持(例如,str 将显示为文本,float 将显示为浮点数,等等)。但是,Excel 本身也支持可视化 pandas.DataFrame 和 numpy.array(最多 2 维),自动显示为 Excel 表格。
如果我们改为将单元格的输出设置为Python 对象,则对象图标将显示在单元格中,紧挨着对象表示本身(或 Python 类的名称)。
此输出很有用,并为对象的实际可视化(例如,图像)提供了灵活性,或者可以用于保存对 Python 对象的引用,以便在工作簿中稍后重用。
3. 使用简短、简单的 Python 代码片段(带输出)
无论您决定为代码单元格设置哪种输出,在 Excel 中编写 Python 代码时都要牢记一些最佳实践。我想要特别强调两点
- 避免编写更长的代码列表。
- 始终返回该单元格的返回值。
在 Excel 单元格中编写 Python 代码与在代码编辑器或集成开发环境 (IDE) 中工作不同。这是因为在 Excel 中使用 Python 的主要目的不是开发 Python 代码,而是使用 Python 来处理Excel(数据),以便创建更强大的数据洞察。
考虑到这一点,最好将 Python 代码保持在最低限度,将自己限制在仅生成所需输出所需的 Python 代码中。此外,在单元格中保持代码片段简短和简单,可以使它们更容易维护。
在 Excel 单元格中编写 Python 代码时要牢记的最后一点是,最好编写生成输出的代码。这主要是因为 Python 代码生成的输出将成为单元格的实际最终内容。Python 公式可以具有多种类型的输出,即文本、数字、Python 对象或图像,所有这些类型都由 Excel 作为单元格内容自动支持。相反,如果您的代码不生成任何输出(例如,Python 公式仅包含 import 语句),则执行代码后单元格的内容将显示为“None”。这完全说得通,因为公式中的 Python 代码根本不生成任何输出;但是,将“None”作为单元格输出可能会让人感觉有点奇怪,或者让其他人看起来像错误。
因此,如果您的 Python 代码没有生成特定输出,最好定义并返回一个 Python 字符串来标记单元格的内容(见下图)。
4. 使用单元格格式正确可视化 Python 输出
在上一条提示中,我们非常强调拥有实际生成输出的 Python 代码。但是它的格式呢?例如,我们可能想要将格式化的字符串放在多行上,或者将浮点数(例如,包含在 Python pandas DataFrame 的一列中)显示为最多两位小数。Python 本身已经提供了用于处理格式化输出的选项。例如,Python 支持格式化的字符串字面量(简称为 f-字符串)来创建由 Python 表达式生成的字符串。Python 字符串也可以是多行(由三引号标识),并包括格式化字符和制表符。
例如,要编写下图所示的 Python 代码,我们可以看到 pi 是用三位小数格式化的,并与字符串的其余部分连接起来。所选 Python 单元格的内容是一个字符串类型的 Python 对象(即 str)。因此,正如预期的那样,单元格的内容是一个 Python 格式化的字符串。
但是,如果我们在单元格中直接写入 pi 的值呢?
如以下图片所示,单元格中生成的输出这次是一个 Python 浮点对象,并自动以九位小数显示。
到目前为止,一切都很好,但如果我们检查单元格的格式选项,我们可能会发现一些有趣的东西。尽管生成的输出是一个浮点数,但您可能会发现应用的单元格格式是“常规”。换句话说,Python 返回的类型(在本例中为 float)和单元格的格式之间没有直接联系。实际上,如果我们选择格式“数字”,然后将小数位数设置为三位,则单元格的新内容应如下面的图片所示。
因此,从现在开始,单元格的内容(在本例中为 B1)将被 Excel 视为数字。
因此,从这条提示中要记住的主要要点是:
- Python 数据类型和单元格格式是两个独立的概念。
- 调整工作簿中单元格的格式,以确保 Excel 正确处理 Python 代码生成的输出,尤其是在输出是数字或日期的情况下。
5. 使用 Python 在 Excel 中创建自定义逻辑
以前,当我们在 Excel 中使用内置函数时,我们调用了该函数(例如,SUM(…)),并立即在单元格中获得了输出。如果我们改为定义要在整个工作簿中使用的函数,我们将不得不使用 Visual Basic for Applications (VBA) 编程语言。现在,我们可以使用 Python 代替!
我们可以在单元格中定义 Python 函数,这些函数然后可以在整个工作簿中的多个单元格中重复使用。实际上,Excel 中 Python 的底层执行模型假定所有单元格共享一个全局命名空间。执行顺序从第一个工作表的左上角单元格开始,并以行优先的方式进行。因此,在单元格中定义的任何变量、Python函数或 Python对象也可以从执行顺序中的所有后续单元格访问和使用。
例如,假设我们要创建一个 Python 函数,该函数生成一个包含给定数量的随机浮点数的数组:
import numpy as np
np.random.seed(42)
def generate_numbers(how_many: int):
return np.random.random(how_many)
generate_numbers(10)
定义函数后,我们调用它生成 10 个不同的随机数。如果您运行此代码,您将获得与下图中显示的相同的数字。
如果您想知道尽管使用了 Python 随机函数,但如何才能获得完全相同的数字,那是因为我们将随机种子固定为 42。因此,伪随机数生成器将重复生成相同的数字序列。
正如预期的那样,该函数生成一个 NumPy Python 数组,所有值都分布在下面的 10 个单元格中。
现在,如果我们在另一个单元格(例如,B1)中重用 generate_numbers 函数,这次为 how_many 输入参数输入不同的值,例如 how_many=5,让我们看看会发生什么
Python 单元格 B1 只包含对 Python 函数的调用,该函数生成另一个包含五个新随机数的数组。因此,我们简单的 Python 函数充当 Excel 自定义逻辑,可以在整个工作簿中定义和重复使用多次,使用不同的参数值。
结论
在这篇文章中,我们探讨了在 Excel 中使用 Python 的五个快速技巧。我们讨论了如何将 Python 对象集成到 Excel 中,如何处理单元格输出及其格式,以及如何使用 Python 创建可重复使用的自定义逻辑。我希望您在开始使用这种激动人心的新集成时发现这些技巧有用。
免责声明:截至本文发表时,Microsoft Excel 中的 Python 集成处于 Beta 测试阶段。功能和函数可能会发生变化。 如果您在此页面上发现错误,请随时联系我们。
简介
Valerio Maggio 是 Anaconda 的研究员和数据科学倡导者。他也是开源贡献者,并且是 Python 社区的活跃成员。在过去的 12 年中,他为许多国际会议和社区聚会做出了贡献并自愿参加,例如 PyCon Italy、PyData、EuroPython 和 EuroSciPy。