写点什么

从 Excel 到 Python

  • 2020-08-04
  • 本文字数:2979 字

    阅读完需:约 10 分钟

从Excel到Python

在 2016 年的 Build 大会上,微软宣布全球有 12 亿人在使用 Excel,而在同一年,全球的人口为 74 亿。也就是说,使用 Excel 的人占全球人口的 16.2%。


2019 年的一份报告( https://slashdata-website-cms.s3.amazonaws.com/sample_reports/ZAamt00SbUZKwB9j.pdf)显示,Python 拥有 820 万活跃开发者,占全球人口的 0.001%。


从这些数据可以看出,增强 Excel 和 Python 之间的交互性对我们是有好处的,这为更多人打开了一扇使用 Python 工具的大门。


Python 在 Excel 前端方面的机会是巨大的。在本文中,我们将分享如何实现一个“典型的”财务 Excel 表格。

先工具,后 Excel

在几乎所有我能想到的场景中,通常是先写 Python 代码,不过必须要保持数据“输入”格式的灵活性。



改变输入数据集格式不应该影响到代码


假设我们使用 Pandas 读取一个或两个 CSV/Excel 表格,可能会依赖一组给定的列名。


如果有数千行这样的代码,我们就依赖了很多硬编码的列名,当我们试图使用 Excel 动态输入列名时,就会遇到问题。


因此,在最初的原型设计阶段,在还没有使用 Excel 工作表时,可以在代码里将列名和内部标签名映射起来:


mappings = {'loan identifier': 'loan_id',               'amt': 'amount',                ...               'init fees': 'initial_fees'}    data.rename(mappings, axis=1, inplace=True) 
复制代码


稍后,这种映射将被 Excel 工作表取代。

Excel 前端

等到 Python 初具模型,就可以开始构建 Excel 前端了。首先,我们要确定哪些变量可以放在 Excel 工作表中。


在开发这类工具时,一般都是要假设输入数据的格式是会变的。


这点要么很重要,要么不那么重要,具体取决于你所在的工作环境以及你要开发什么样的工具。有些工作流程定义得比较好,数据格式不太可能会发生变化。


但是,我总是会倾向于保持谨慎,希望通过 Excel 来增加灵活性,但要注意不要将事情复杂化。



使用 Excel 将 Python 内部列名与外部 CSV/Excel 列名映射起来


使用内部命名系统并允许 Excel 用户指定列映射,这是保持灵活性的一个很好的例子。现在,Excel 用户不再依赖于硬编码的列名,他们可以在不修改 Python 代码的情况下调整列映射。

映射

mappings 是集成的核心部分,它的内容来自 Excel 中的一张表(我通常会叫它 Mapping)。


要得到 mappings,我们需要一个函数来读取 Excel。为此,我们使用了 openpyxl。


我们可以这样读取 Excel 中的单元格:


import openpyxl # 加载工作簿 wb = openpyxl.load_workbook("sheet.xlsx", data_only=True) # 创建工作簿对象 ws = wb.active # 获取单元格E4的值 value = ws['E4'].value 
复制代码


我们可以通过这种方式得到 mappings。我们将代码稍作调整,添加 Excel 工作簿“tool_setup.xlsx”本地路径。


我们还要假设 Excel 的当前工作表可能不是我们想要的那个,而且可能会新增、被删除或被移动,所以我们需要通过遍历找到目标工作表的索引位置:


# 首先,我们设置Excel文件的路径 path = r".\documents\tool_setup.xlsx" # 加载文件,创建工作簿对象 wb = openpyxl.load_workbook(path, data_only=True) # 找到目标工作表的索引 idx = [i for i, name in wb.sheetnames if name == 'Mapping'][0] # 将目标工作表设置为当前工作表 wb.active = idx ws = wb.active 
复制代码


现在,我们可以填充 mappings 内容了 :


mappings = {} mappings['Amount'] = ws["E4"].value mappings['Term'] = ws["E5"].value 
复制代码

保持灵活性

如果工作表里添加了新行或者把旧行删除,有可能会得到一个不正确的 mappings。为了避免这种情况,我们需要 search_col 函数,它会遍历查找每个单元格,直到找到包含我们想要的值(或超过 limit 限制)的单元格。


# 定义一个函数,用于查找openpyxl工作簿对象中的给定列 def search_col(sheet, column, value, limit=100):      # 从1开始,逐行查找,直到达到limit限制     for row in range(1, limit+1):                if sheet[f"column{row}"].value == value:             # 找到想要的单元格,返回单元格的列和行             return (col, row) 
复制代码


search_col 返回我们想要的数据的列和行。



如果没处理好,哪怕是在工作表里添加一个注释也会让工具不可用。左边的“Internal”在第 12 行,而右边是第 14 行。


我们可以像下面这样找到“Internal”的单元格位置:


search_col(ws, 'B', 'Internal') [Out]: ('B', 12) 
复制代码


接下来,我们通过循环往 mappings 添加其他列映射。在遇到两个或者更多个空的单元格后,我们就知道映射内容已经全部读取完毕,就可以结束循环了:


empty = 0  # 初始化空单元格数量 while empty < 2:     # 增加行计数     row += 1     # 赋值     internal = ws[f'B{row}'].value          if internal is None:         empty += 1  # 遇到空单元格就增加空单元格计数     else:         # 加入mappings         mappings[internal] = ws[f'D{row}'].value         empty = 0  # also re-initialize the empty counter 
复制代码


运行上面的代码,就可以得到像下面这样的 mappings:


{     'Loan ID': 'loan identifier',     'Product': 'product type',      ...     'Initial Fees': 'init fees' } 
复制代码


如果要引入其他变量,比如文件路径(filepath),我们只需要找到包含“Filepath”的单元格,并把它的值赋给“filepath”:


row, _ = search_col(ws, 'C', 'Filepath') mappings['filepath'] = ws[f'D{row}].value 
复制代码

集成

最后一步,也是最容易的一步——在 Python 脚本中使用列名。


我们使用上面得到的 mappings,将输入列名转成内部标签。


data = pd.read_csv(mappings['Filepath']) 
复制代码


在将输入列名转成内部标签之前,我们必须翻转键值对,即把键-值转成值-键。


# 翻转 inv_mappings = {mappings[key]: key for key in mappings} 
复制代码


对于这个简单的例子,或许在构建 mappings 时就进行翻转会更方便些。对于复杂一点的工具,我发现使用内部到外部的映射格式会更好。但不管怎样,这一切取决于你自己。


最后,将输入列名转成内部标签:


data.rename(inv_mappings, axis=1, inplace=True) 
复制代码


我们可以做得更灵活一些。为了处理不必要的空格或大小写拼写错误,我们重写了一小部分代码:


data = pd.read_csv(mappings['Filepath']) # 转成小写,剔除不必要的空格 data.rename({col: col.strip().lower() for col in data.columns},             axis=1, inplace=True) # inv_mappings也是一样 # 内部标签使用蛇形命名方式 (不是必需的) inv_mappings = {     mappings[key].strip().lower():         key.strip().lower().replace(' ', '_')     for key in mappings } # 现在安全了 data.rename(inv_mappings, axis=1, inplace=True) 
复制代码


另外,我们在 Excel 中显示内部标签时通常会使用首字母大写和正常空格,而在内部我个人还是选择蛇形命名格式。


"Loan ID" -> "loan_id" "Initial Rate" -> "initial_rate" 
复制代码

结论

我曾见过无数家重度使用 Excel 的公司,这么做可以节省数百个小时用于检查单元格、输入值或等待 Excel 模型处理数据的时间。


尽管自动化和机器学习时代正在迅速地将 Excel 的很多领域自动化,但 Excel 不会很快就消失掉。


目前,世界上发展最快的编程语言(Python)和世界上使用最为广泛的软件(Excel)之间的紧密集成可以给很多行业带来巨大收益。


原文链接:


https://towardsdatascience.com/excel-to-python-79b01638f2d9


2020-08-04 18:334493

评论 1 条评论

发布
用户头像
感觉还是管理Excel这个产品比Python更能和excel对接拓展
2020-08-05 11:04
回复
没有更多了
发现更多内容

2022年盲盒软件开发商业模式深度解析

开源直播系统源码

软件开发 盲盒开发 盲盒软件

SAP Marketing Cloud 功能概述(二)

汪子熙

云计算 SaaS SAP 6月月更 Marketing Cloud

Gitlab运维篇之——备份及恢复

阿呆

#GitLab 备份恢复

如何进行高效简洁的电子文档管理

小炮

【直播回顾】战码先锋第六期:共建测试子系统,赋能开发者提高代码质量

OpenHarmony开发者

OpenHarmony

【OpenI开源项目推荐-GammaGL】支持国内外主流深度学习框架的图神经网络算法库

OpenI启智社区

人工智能 算法 图神经网络

重磅直播|BizDevOps:数字化转型浪潮下的技术破局之路

阿里云云效

阿里云 DevOps 研发效能 BizDevOps 场数字化转型

深圳java培训 | Java设计模式之建造者模式

@零度

设计模式 JAVA开发

java培训机构 | Java设计模式之适配器模式

@零度

设计模式 JAVA开发

云上人和物联科技加入龙蜥社区,携手打造软硬件服务生态

OpenAnolis小助手

开源 生态 龙蜥社区 CLA 云上人和物联科技

北京大数据培训 | 电商用户行为分析之实时流量统计

@零度

大数据开发

DingOS服务提交IPO配置指南

鼎道智联

前端 开发 IPO配置

今天,SysAK 是如何实现业务抖动监控及诊断?&手把手带你体验Anolis OS|第25-26期

OpenAnolis小助手

Linux sig 龙蜥大讲堂 开源贡献 社区运维

本周四晚19:00战码先锋第7期直播丨三方应用开发者如何为开源做贡献

OpenHarmony开发者

OpenHarmony

Java自定义Once方法保障单次执行

FunTester

PHP开发的网站,如何实现批量打印快递单的功能?

迷彩

编程 记录 开发 php扩展 6月月更

CAT敏捷团队教练工作坊 (Coaching Agile Teams) | 8月20日开课

ShineScrum

教练 敏捷教练 高管教练 专业教练 ACC

TiFlash 函数下推必知必会丨十分钟成为 TiFlash Contributor

PingCAP

#TiDB

MAUI使用Masa blazor组件库

沙漠尽头的狼

Java——流输入输出

武师叔

6月月更

得物技术复杂 C 端项目的重构实践

得物技术

前端 大前端 重构 框架 社区

缓存穿透利器之「布隆过滤器」

Ayue、

redis 布隆过滤器

智能合约dapp系统开发模式定制方案

开发微hkkf5566

NFT交易平台数字藏品系统开发技术

薇電13242772558

NFT 数字藏品

Java——I/O II

武师叔

6月月更

社恐?自我介绍时大脑一片空白?

阿Q说代码

个人成长 社恐 职场破冰 入职公司

攻防演练 | 基于ATT&CK的威胁狩猎实践案例

青藤云安全

网络安全 攻防演练 威胁狩猎

初识ElasticSearch

阿Q说代码

搜索引擎 lucene ES 选举 脑裂

社区文章|MOSN 构建 Subset 优化思路分享

SOFAStack

负载均衡 开源 开发者 算法

企业官网如何提高客户转化率

源字节1号

美团基于 Flink 的实时数仓平台建设新进展

Apache Flink

大数据 flink 流计算 实时计算 实时数仓

从Excel到Python_语言 & 开发_James Briggs_InfoQ精选文章