独家 | 10个数据科学家常犯的编程错误(附解决方案)

简介: 本文为资深数据科学家常见的10个错误提供解决方案。

作者:Norman Niemer

翻译:李润嘉

校对:李洁

文章来源:微信公众号 数据派THU

本文约2000字,建议阅读10分钟。

本文为资深数据科学家常见的10个错误提供解决方案。

----

数据科学家是“比软件工程师更擅长统计学,比统计学家更擅长软件工程的人”。许多数据科学家都具有统计学背景,但是在软件工程方面的经验甚少。我是一名资深数据科学家,在Stackoverflow的python编程方面排名前1%,并与许多(初级)数据科学家共事。以下是我经常看到的10大常见错误,本文将为你相关解决方案:

  • 不共享代码中引用的数据
  • 对无法访问的路径进行硬编码
  • 将代码与数据混合
  • 在Git中和源码一起提交数据
  • 编写函数而不是DAG
  • 写for循环
  • 不编写单元测试
  • 不写代码说明文档
  • 将数据保存为csv或pickle文件
  • 使用jupyter notebook

1. 不共享代码中引用的数据

数据科学需要代码和数据。因此,为了让别人可以复现你的结果,他们需要能够访问到数据。道理很简单,但是很多人忘记分享他们代码中的数据。

import pandas as pd
df1 = pd.read_csv('file-i-dont-have.csv') # fails
do_stuff(df)

解决方案:使用d6tpipe(https://github.com/d6t/ d6tpipe)来共享你的代码中的数据文件、将其上传到S3/web/google驱动等,或者保存到数据库,以便于别人可以检索到文件(但是不要将其添加到git,原因见下文)。

2. 对无法访问的路径进行硬编码

与错误1相似,如果你对别人无法访问的路径进行硬编码,他们将无法运行你的代码,并且必须仔细查看代码来手动更改路径。令人崩溃!


import pandas as pd
df = pd.read_csv('/path/i-dont/have/data.csv') # fails
do_stuff(df)

# or
import os
os.chdir('c:\\Users\\yourname\\desktop\\python') # fails

解决方案:使用相对路径、全局路径配置变量或d6tpipe,使你的数据易于访问。

d6tpipe:

https://github.com/d6t/d6tpip

3. 将代码与数据混合

既然数据科学的代码中包含数据,为什么不把它们放到同一目录中?那样你还可以在其中保存图像、报告和其他垃圾。哎呀,真是一团糟!


├── data.csv
├── ingest.py
├── other-data.csv
├── output.png
├── report.html
└── run.py

解决方案:将你的目录进行分类,比如数据、报告、代码等。请参阅Cookiecutter Data Science或d6tflow项目模板[见#5],并使用#1中提到的工具来存储和共享数据。

Cookiecutter Data Science:

https://drivendata.github.io/cookiecutter-data-science/

d6tflow项目模板:

https://github.com/d6t/d6tflow-templat

4. 在Git中和源码一起提交数据

现在,大多数人对他们的代码使用版本控制(如果你不使用,那就是另外一个错误,请参阅git:https://git-scm.com/)。在尝试共享数据时,很容易将数据文件添加到版本控制中。当文件很小时是可以的,但是git并没有针对数据进行优化,尤其是大文件。


git add data.csv

解决方案:使用第1点中提到的工具来存储和共享数据。如果你真的希望对数据进行版本控制,请参阅 d6tpipe,DVC和Git大文件存储。

d6tpipe:

https://github.com/d6t/d6tpipe

DVC:

https://dvc.org/

Git大文件存储:

https://git-lfs.github.com

5. 编写函数而不是DAG

关于数据部分已经够多了,现在来谈一谈实际的代码!在学习编程时最先学习的内容之一就是函数,数据科学代码通常由一系列线性运行的函数组成。

这会导致一些问题,请参阅“为什么你的机器学习代码可能不好的4个原因”:

https://github.com/d6t/d6t-python/blob/master/blogs/reasons-why-bad-ml-code.rst

def process_data(data, parameter):
 data = do_stuff(data)
 data.to_pickle('data.pkl')
 
data = pd.read_csv('data.csv')
process_data(data)
df_train = pd.read_pickle(df_train)
model = sklearn.svm.SVC()
model.fit(df_train.iloc[:, :-1], df_train['y'])

解决方案:数据科学代码不是一系列线性连接的函数,而是一组具有依赖关系的任务集合。请使用d6tflow或airflow。

d6tflow:

https://github.com/d6t/d6tflow-template

airflow:

https://airflow.apache.org

6. 写for循环

与函数类似,for循环也是你学习编程时最初学习的内容。它们易于理解,但是运行缓慢且过于冗长,通常意味着你不了解矢量化的替代方案。


x = range(10)
avg = sum(x)/len(x); std = math.sqrt(sum((i-avg)**2 for i in x)/len(x));
zscore = [(i-avg)/std for x]
# should be: scipy.stats.zscore(x)
# or
groupavg = []
for i in df['g'].unique():
dfg = df[df[g']==i]
groupavg.append(dfg['g'].mean())
# should be: df.groupby('g').mean()

解决方案:Numpy,scipy和pandas为你需要for循环的情况提供了矢量化函数。

Numpy:

http://www.numpy.org/

scipy:

https://www.scipy.org/

pandas:

https://pandas.pydata.org

7. 不编写单元测试

随着数据、参数或用户输入的改变,你的代码可能会出现问题,有时你并没有注意到。这可能会导致糟糕的输出结果,而如果有人基于你的输出做出决策,那么糟糕的数据将会导致糟糕的决策。

解决方案:使用assert语句来检查数据质量。pandas有相等测试,d6tstack有数据提取检查以及用于数据连接的d6tjoin。

pandas相等测试:

https://pandas.pydata.org/pandas-docs/stable/reference/general_utility_functions.html

d6tstack:

https://github.com/d6t/d6tstack

d6tjoin:

https://github.com/d6t/d6tjoin/blob/master/examples-prejoin.ipyn

以下是数据检查的示例代码:

assert df['id'].unique().shape[0] == len(ids) # have data for all ids?
assert df.isna().sum()<0.9 # catch missing values
assert df.groupby(['g','date']).size().max() ==1 # no duplicate values/date?
assert d6tjoin.utils.PreJoin([df1,df2],['id','date']).is_all_matched() # all ids matched?

8. 不写代码说明文档

我明白,你急着做出一些分析结果。你把事情汇总到一起分析,将结果交给你的客户或老板。一个星期之后,他们回来说,“可以把XXX改一下吗”或者“可以更新一下这里吗”。你看着你的代码,但是并不记得你当初为什么这么写。现在就像是在运行别人的代码。

def some_complicated_function(data):
 data = data[data['column']!='wrong']
 data = data.groupby('date').apply(lambda x: complicated_stuff(x))
 data = data[data['value']<0.9]
 return data

解决方案:即使在你已经提交分析报告后,也要花费额外的时间,来对你做的事情编写说明文档。以后你会感谢自己,别人更会感谢你。那样显得你很专业!

9. 将数据保存为csv或pickle文件

回到数据,毕竟是在讲数据科学。就像函数和for循环一样,CSV和pickle文件很常用,但是并不好用。CSV文件不包含纲要(schema),因此每个人都必须再次解析数字和日期。Pickle文件解决了这个问题,但是它只能在python中使用,并且不能压缩。两者都不是存储大型数据集的最优格式。

def process_data(data, parameter):
    data = do_stuff(data)
    data.to_pickle('data.pkl')
    
data = pd.read_csv('data.csv')
process_data(data)
df_train = pd.read_pickle(df_train)

解决方案:使用parquet或其他带有数据纲要的二进制数据格式,在理想情况下可以压缩数据。d6tflow将任务的数据输出保存为parquet,无需额外处理。

parquet:

https://github.com/dask/fastparquet

d6tflow:

https://github.com/d6t/d6tflow-template

10. 使用jupyter notebook

最后一个是颇有争议的错误:jupyter notebook和csv文件一样普遍。许多人使用它们,但是这并不意味着它们很好。jupyter notebook助长了上述提到的许多不良编程习惯,尤其是:

把所有文件保存在一个目录中

编写从上至下运行的代码,而不是DAG

没有对代码进行模块化

很难调试

代码和输出混在一个文件中

没有很好的版本控制

它容易上手,但是扩展性很差。

解决方案:使用pycharm和/或spyder。

pycharm:

https://www.jetbrains.com/pycharm/

spyder:

https://www.spyder-ide.org

作者简介:Norman Niemer是一家大规模资产管理公司的首席数据科学家,他在其中发布数据驱动的投资见解。他有哥伦比亚大学的金融工程专业理学硕士学位,和卡斯商学院(伦敦)的银行与金融专业理学学士学位。

原文标题:

Top 10 Coding Mistakes Made by Data Scientists

原文链接:

https://github.com/d6t/d6t-python/blob/master/blogs/top10-mistakes-coding.md

译者简介

李润嘉,首都师范大学应用统计硕士在读。对数据科学和机器学习兴趣浓厚,语言学习爱好者。立志做一个有趣的人,学想学的知识,去想去的地方,敢想敢做,不枉岁月。

翻译组招募信息

工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

目录
相关文章
|
8月前
|
安全 编译器 测试技术
PHP 8 新特性解析:JIT编译器如何提升你的应用性能
PHP 8 新特性解析:JIT编译器如何提升你的应用性能
353 114
|
11月前
|
存储 安全 对象存储
10 天挑战不可能! 30TB 跨大洲云主机迁移!
客户将巴西至非洲超7000公里跨洲36台Windows虚拟机(30TB数据)迁移至南非云节点,面临网络延迟、传输慢、停机窗口短等挑战。通过HyperMotion技术实现增量同步与并发传输,结合对象存储优化,10天内完成全量及多次增量同步,停机窗口最短仅2小时,项目周期从预估6个月压缩至10天,成本不足专线方案10%,保障业务零中断,为全球跨区域迁移提供创新范本。
492 2
|
12月前
|
人工智能 运维 安全
科技云报到:Agent应用爆发,谁成为向上托举的力量?
AI正加速迈入Agent时代,具备推理、规划与工具调用能力的智能体,正重塑企业应用形态。2025年,AI Agent基础设施迎来爆发,云厂商纷纷推出新一代技术架构,突破长时运行、状态管理、安全隔离等关键难题,推动Agent从实验室走向千万级企业场景。算力、工具链与安全等挑战逐步被攻克,AI Agent正成为企业智能化转型的核心驱动力。
785 0
|
移动开发 前端开发 安全
【HarmonyOS next】ArkUI-X休闲益智消消乐【进阶】
本项目基于ArkUI-X实现H5游戏与原生应用融合,通过Web组件将Vue+Canvas开发的消消乐游戏无缝嵌入ArkTS容器,支持HarmonyOS与iOS双平台运行。核心包括:跨端渲染适配、高性能动画引擎、触控事件归一化及多端性能优化,代码复用率达92%,帧率稳定≥55FPS,触控延迟<80ms。提供完整源码与开发建议,拓展方向涵盖分布式续玩与原生能力集成。
440 0
|
监控 测试技术 数据库连接
利用 RunnerGo 深度探索 API 性能测试:从理论到实践
API性能测试是保障应用稳定性和用户体验的关键环节。本文详细探讨了如何使用RunnerGo全栈测试平台进行高效API性能测试,涵盖测试计划创建、场景设计、参数配置到执行与分析全过程。通过电商平台促销活动案例,展示了高并发下的测试策略与优化措施,如代码与数据库查询优化、数据库连接池扩容、服务器资源配置调整及缓存策略实施等。最终显著提升系统性能,满足高并发需求。API性能测试需持续关注与优化,以适应业务发展和用户需求变化。
535 33
|
JSON 数据挖掘 API
搜款网VVIC商品列表数据接口(搜款网API系列)
搜款网(VVIC)是知名服装批发平台,开发者可通过API获取商品列表数据,用于市场调研、数据分析等。API请求通常为HTTP GET,需申请权限并提供API Key。响应数据为JSON格式,包含商品基本信息。Python示例代码展示了如何发送请求和处理响应。使用API时需确保合法合规,注意错误处理和性能优化。
|
安全 API 开发者
微信开发者工具里面没有企业微信模式
企业微信与普通微信在应用场景和开发体系上存在本质区别,主要体现在身份认证、功能丰富性和开放能力等方面。企业微信开发需使用特定的API和工具,本文介绍了企业微信开发的基本步骤、特点及开发进度安排,帮助开发者更好地理解和应用企业微信的开发环境。
|
机器学习/深度学习 数据采集 人工智能
【AI在金融科技中的应用】详细介绍人工智能在金融分析、风险管理、智能投顾等方面的最新应用和发展趋势
人工智能(AI)在金融领域的应用日益广泛,对金融分析、风险管理和智能投顾等方面产生了深远影响。以下是这些领域的最新应用和发展趋势的详细介绍
2116 1
|
SQL 数据采集 算法
【电商数据分析利器】SQL实战项目大揭秘:手把手教你构建用户行为分析系统,从数据建模到精准营销的全方位指南!
【8月更文挑战第31天】随着电商行业的快速发展,用户行为分析的重要性日益凸显。本实战项目将指导你使用 SQL 构建电商平台用户行为分析系统,涵盖数据建模、采集、处理与分析等环节。文章详细介绍了数据库设计、测试数据插入及多种行为分析方法,如购买频次统计、商品销售排名、用户活跃时间段分析和留存率计算,帮助电商企业深入了解用户行为并优化业务策略。通过这些步骤,你将掌握利用 SQL 进行大数据分析的关键技术。
1373 0
|
JavaScript
ts(typescript)面向对象之类的继承
super当作属性使用的时候, super 指向的是父类的原型,因此super无法拿到父类的实例属性,只能拿到父类的public和protected的方法,super 如果当方法使用的话,只能在字类的构造函数中并且是第一行使用,需要使用super()来实例化父类里面的属性,确保字类可以获取父类的成员。
ts(typescript)面向对象之类的继承

热门文章

最新文章