数据科学家比软件工程师更擅长统计学,比统计学家更擅长软件工程。听起来很棒,但事实是许多数据科学家具有统计学背景,但在软件工程方面经验不足,因此在编码时容易犯简单的错误。作为资深数据科学家,本文作者总结了数据科学家在工作中常犯的十大错误。我是一名高级数据科学家,在Stackoverflow上的Python编码排名前1%,并且还与许多(初级)数据科学家一起工作。下面列出了我看到的10个常见错误。1.共享代码中没有引用数据数据科学需要代码和数据。所以为了让别人重现你所做的结果,你需要提供代码中涉及的数据。这看起来很简单,但是很多人忘记在他们的代码中共享他们需要的数据。importpandasaspddf1=pd.read_csv('file-i-dont-have.csv')#failsdo_stuff(df)解决方法:代码中使用d6tpipe共享数据文件,或者将数据文件上传到S3/网页/谷歌云等.,也可以将数据文件保存到数据库中,以便接收者可以检索文件(但不要将数据添加到git,稍后会介绍)。2.Hardcodingapaththatotherscannotaccess与错误1类似,如果你硬编码了一个别人不能访问的路径,他们将无法运行你的代码,你将不得不在很多地方手动修改路径。Booo!importpandasassspddf=pd.read_csv('/path/i-dont/have/data.csv')#failsdo_stuff(df)#orimporosos.chdir('c:\\Users\\yourname\\desktop\\python')#fails解决方案:使用相对路径、全局路径配置变量或d6tpipe,以便其他人可以轻松访问您的数据。3.混合数据和代码既然数据科学代码需要数据,为什么不把代码和数据放在同一个目录下呢?但是当你运行代码时,这个目录还会存储图像、报告和其他垃圾文件。混乱!├──data.csv├──ingest.py├──other-data.csv├──output.png├──report.html└──run.py解决办法:对目录进行排序,比如data,reports,代码等请参阅CookiecutterDataScience或d6tflow项目模板,并使用问题1中提到的工具来存储和共享数据。Cookiecutter数据科学:https://drivendata.github.io/cookiecutter-data-science/#directory-structured6tflow项目模板:https://github.com/d6t/d6tflow-template4。使用Git提交数据现在大多数人都对他们的代码进行版本控制(如果你不这样做,那是另一个问题!)。共享数据时,可能很容易将数据文件添加到版本控制中。对于一些小文件,这很好。但是git不能优化数据,尤其是大文件。gitadddata.csv解决方案:使用问题1中提到的工具来存储和共享数据。如果您确实需要对数据进行版本控制,请参阅d6tpipe、DVC和Git大型文件存储。DVC:https://dvc.org/Git大文件存储:https://git-lfs.github.com/5。写函数代替DAG数据已经讨论够了,我们来谈谈实际的代码。当您学习编程时,您首先会了解函数,而数据科学代码主要由一系列以线性方式运行的函数组成。这就提出了一些问题,详见“4ReasonsWhyYourMachineLearningCodeProbablyBad”。“地址:https://towardsdatascience.com/4-reasons-why-your-machine-learning-code-is-probably-bad-c291752e4953defprocess_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或者airflow6.写for循环和函数一样,for循环先thingyoulearnwhenyoulearntocode.这种语句很容易理解,但速度慢且冗长,这通常表明您不知道用什么代替向量化。x=range(10)avg=sum(x)/len(x);std=math.sqrt(sum((i-avg)**2foriinx)/len(x));zscore=[(i-avg)/stdforx]#shouldbe:scipy.stats.zscore(x)#orgroupavg=[]foriindf['g'].unique():dfdfg=df[df[g']==i]groupavg.append(dfg['g'].mean())#shouldbe:df.groupby('g').mean()解决方案:NumPy,SciPy,pandas具有矢量化函数,可以处理您认为需要使用for循环来解决问题的大部分事情。7.不写单元测试随着数据、参数或用户输入的变化,你的代码可能会崩溃,而你有时可能没有注意到。这会导致错误的输出,如果有人根据你的输出做出决定,那么错误的数据会导致错误的决定!解决方案:使用assert语句检查数据质量。pandas也有同样的测试,d6tstack可以检查数据抓取,d6tjoin可以检查数据连接。检查数据的示例代码如下:].unique().shape[0]==len(ids)#havedataforallids?assertdf.isna().sum()<0.9#catchmissingvaluesassertdf.groupby(['g','date']).size().max()==1#noduplicatevalues/date?assertd6tjoin.utils.PreJoin([df1,df2],['id','date']).is_all_matched()#allidsmatched?8.没有注释代码,我明白你急于做分析。所以你把代码拼凑起来得到结果,然后把结果给你的客户或老板。一周后,他们来找你,问你“你能改变xyz吗?”或“你能更新结果吗?”。然后你茫然地盯着自己的代码,既不记得你为什么这样做,也不记得你做了什么。现在想象一下其他人在运行这段代码时的感受。defsome_complicated_function(数据):datadata=data[data['column']!='wrong']datadata=data.groupby('date').apply(lambdax:complicated_stuff(x))datadata=data[data['value']<0.9]returndata解决方案:即使您已经完成分析,也要花时间记下您所做的事情。你会感谢自己,当然别人会更加感谢你!这样你会看起来更专业!9.将数据保存为csv或pickle,再说回数据,毕竟我们说的是数据科学。与函数和for循环一样,CSV和pickle文件也很常用,但它们并不是那么好用。CSV不包含架构,因此每个人都必须重新解析数字和日期。Pickle可以解决这个问题,但它只能在Python中使用,并且不能压缩。这两种格式都不适合存储大型数据集。defprocess_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可以自动将数据输出存储为镶木地板,因此您不必处理这个问题。镶木地板:https://github.com/dask/fastparquet10。使用Jupyternotebook的结论还是有些争议——Jupyternotebook和CSV一样常用。许多人使用它们。但这并没有让他们变得更好。Jupyternotebooks助长了上面提到的许多不良软件工程习惯,特别是:将所有文件存储在一个目录中;你编写自上而下运行的代码,而不是DAG;你没有模块化你的代码;代码很难调试;代码和输出将混合在一个文件中;版本控制不好。Jupyter笔记本很容易上手,但太小了。解决方案:使用pycharm和/或spyder。原文链接:https://medium.com/m/global-identity?redirectUrl=https%3A%2F%2Ftowardsdatascience.com%2Ftop-10-coding-mistakes-made-by-data-scientists-bb5bc82faaee【本文为专栏《机器之心》组织原译,微信公众号《机器之心(id:almosthuman2014)》】点此查看作者更多好文
