【.com快译】数据科学家是“比任何软件工程师更擅长统计方法,比任何统计学家更擅长软件工程的人”。许多数据科学家研究过统计学,但在软件工程方面的经验很少。我是一名高级数据科学家,接触过许多(初级)数据科学家。以下是我经常看到的10个常见错误。1.不要共享代码中引用的数据数据科学需要代码和数据。因此,为了让其他人能够重现您的结果,他们需要能够访问数据。这可能看起来很基本,但很多人忘记在他们的代码中共享数据。importpandasaspddf1=pd.read_csv('file-i-dont-have.csv')#failsdo_stuff(df)解决方法:使用d6tpipe将你的代码共享数据文件,上传到S3/web/googledrive等,或者保存到数据库,以便接收方可以检索文件(但不要将它们添加到git,详情请参见下文)。2.硬编码无法访问的路径与错误#1类似,如果您对其他人无法访问的路径进行硬编码,他们将无法运行您的代码并且必须查看很多地方以手动更改路径。太糟糕了!importpandasaspddf=pd.read_csv('/path/i-dont/have/data.csv')#failsdo_stuff(df)#orimportosos.chdir('c:\\Users\\yourname\\desktop\\python')#fails解决方法:使用相对路径、全局路径配置变量或d6tpipe使您的数据易于访问。3.数据与代码混合既然数据科学代码需要数据,为什么不把数据放在同一个目录下呢?这样,您还可以在处理图像、报告和其他内容时将其保存在那里。真是一团糟!├──data.csv├──ingest.py├──other-data.csv├──output.png├──report.html└──run.py代码等。请参阅CookiecutterDataScience项目,使用第1点中提到的工具存储和共享数据。4.Git提交数据和源代码现在大多数人对他们的代码进行版本控制。如果你不这样做,那就是另一个错误!见混帐。尝试共享数据时,可能很想将数据文件添加到版本控制中。这对于非常小的文件来说很好,但是git没有针对数据(尤其是大文件)进行优化。gitadddata.csv解决方案:使用第1点中提到的工具来存储和共享数据。如果您真的想对数据进行版本控制,请参阅d6tpipe、DVC和Git大文件存储。5.说完写函数而不是DAG数据,让我们来谈谈实际代码!学习编程时要理解的最重要的事情之一是函数,数据科学代码主要组织为一系列以线性方式运行的函数。这会导致几个问题,请参阅《你的机器学习代码可能很糟糕的4个原因》。defprocess_data(数据,参数):data=do_stuff(data)data.to_pickle('data.pkl')data=pd.read_csv('data.csv')process_data(数据)df_train=pd.read_pickle(df_train)model=sklearn.svm.SVC()model.fit(df_train.iloc[:,:-1],df_train['y'])解决方案:数据科学代码被编写为一组相互依赖的任务,而不是线性连接的函数。可以使用d6tflow或airflow。6.写for循环和函数一样,for循环是你学习编程的第一件事。易于理解,但它们速度慢且过于冗长,通常表明您不知道替代的向量化函数。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():dfg=df[df[g']==i]groupavg.append(dfg['g'].mean())#shouldbe:df.groupby('g').mean()解决方案:Numpy、scipy和pandas具有矢量化函数,可以处理您认为循环可能需要的大多数任务。7.不要编写单元测试随着数据、参数或用户输入的变化,代码可能会崩溃,而有时您并不知道。这会导致不良的输出;如果有人根据你的输出做出决定,那么糟糕的数据会导致糟糕的决定!解决方案:使用断言语句检查数据质量。Pandas具有相等性测试,d6tstack检查数据摄取,d6tjoin检查数据连接。示例数据检查代码如下:assertdf['id'].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(data):data=data[data['column']!='wrong']data=data.groupby('date').apply(lambdax:complicated_stuff(x))data=data[data['value']<0.9]returndata解决方法:即使你已经提交了分析,拿一些是时候记录你写的代码了。你会感谢你自己,别人也会感谢你!这样你看起来很专业!9.将数据保存为csv或pickle回到数据,毕竟它是数据科学。像函数和for循环一样,CSV和pickle文件用得很多,但它们并不是很好。CSV不包含模式,因此每个人都必须重新解析数字和日期。Pickles解决了这个问题,但只适用于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自动将任务的数据输出保存为parquet,因此您不必处理它。10.使用jupyternotebook***一个有争议的错误:jupyternotebook和CSV一样普遍。仅仅因为很多人使用它们并不意味着它们很好。jupyternotebooks助长了上面提到的许多不良的软件工程习惯,尤其是:你情不自禁地想将所有文件放在一个目录中你编写自上而下运行的代码,而不是DAG你不编写代码模块化难以调试代码和输出混合在一个文件中没有良好的版本控制上手容易,但可扩展性差。解决方案:使用pycharm和/或spyder。原标题:数据科学家犯的十大编码错误,作者:NormanNiemer
