news 2026/1/13 10:15:45

如何减少 Python 处理繁重任务的运行时间

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何减少 Python 处理繁重任务的运行时间

原文:towardsdatascience.com/how-to-reduce-python-runtime-for-demanding-tasks-2857efad0cec

数据科学家面临的最大挑战之一是处理极大数据集或高度复杂的机器学习/深度学习模型时 Python 代码运行时间过长。许多方法已被证明可以有效提高代码效率,例如降维、模型优化和特征选择——这些都是基于算法的解决方案。另一种应对这一挑战的方法是在某些情况下使用不同的编程语言。在今天的文章中,我不会专注于基于算法的改进代码效率的方法。相反,我将讨论既方便又容易掌握的实际技术。

为了说明,我将使用在线零售数据集,这是一个在 Creative Commons Attribution 4.0 International (CC BY 4.0)许可下的公共数据集。您可以从 UCI 机器学习仓库下载原始的在线零售数据集。该数据集包含在英国注册的非实体店在线零售商在特定期间发生的所有交易数据。目标是训练一个模型来预测客户是否会进行回购,以下 Python 代码用于实现这一目标。

importpandasaspdfromsklearn.model_selectionimporttrain_test_splitfromsklearn.ensembleimportRandomForestClassifierfromitertoolsimportproduct# Load dataset from Excel filedata=pd.read_excel('Online Retail.xlsx',engine='openpyxl')# Data preprocessingdata=data.dropna(subset=['CustomerID'])data['InvoiceYearMonth']=data['InvoiceDate'].astype('datetime64[ns]').dt.to_period('M')# Feature Engineeringdata['TotalPrice']=data['Quantity']*data['UnitPrice']customer_features=data.groupby('CustomerID').agg({'TotalPrice':'sum','InvoiceYearMonth':'nunique',# Count of unique purchase months'Quantity':'sum'}).rename(columns={'TotalPrice':'TotalSpend','InvoiceYearMonth':'PurchaseMonths','Quantity':'TotalQuantity'})# Create the target variablecustomer_features['Repurchase']=(customer_features['PurchaseMonths']>1).astype(int)# Train-test splitX=customer_features.drop('Repurchase',axis=1)y=customer_features['Repurchase']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# Model trainingclf=RandomForestClassifier()clf.fit(X_train,y_train)# Define different values for parametersn_estimators_options=[50,100,200]max_depth_options=[None,10,20]class_weight_options=[None,'balanced']# Train the RandomForestClassifier with different combinations of parametersresults=[]forn_estimators,max_depth,class_weightinproduct(n_estimators_options,max_depth_options,class_weight_options):clf=RandomForestClassifier(n_estimators=n_estimators,max_depth=max_depth,class_weight=class_weight,random_state=42)clf.fit(X_train,y_train)accuracy=clf.score(X_test,y_test)results.append((n_estimators,max_depth,class_weight,accuracy))

由于处理了 541,909 行数据,运行代码需要一些时间。在电子商务或社交媒体等行业,数据科学家经常处理更大的数据集——有时是数十亿甚至数万亿行数据,具有更多特征。还有结构化和非结构化数据的组合,文本、图像或视频——这些各种类型的数据无疑增加了工作量。因此,应用一些技术来优化代码效率至关重要。我将坚持使用在线零售数据来简化解释。在介绍这些技术之前,我测量了运行整个 Python 脚本、读取在线零售数据和训练机器学习模型所需的时间。

importtime# Function to calculate and print elapsed timedeftime_execution(func,*args,**kwargs):start_time=time.time()result=func(*args,**kwargs)elapsed_time=time.time()-start_timereturnresult,elapsed_time# 1\. Full Python code execution timingdefcomplete_process():# Load dataset from Excel filedata=pd.read_excel('Online Retail.xlsx',engine='openpyxl')# Data preprocessingdata=data.dropna(subset=['CustomerID'])data['InvoiceYearMonth']=data['InvoiceDate'].astype('datetime64[ns]').dt.to_period('M')# Feature Engineeringdata['TotalPrice']=data['Quantity']*data['UnitPrice']customer_features=data.groupby('CustomerID').agg({'TotalPrice':'sum','InvoiceYearMonth':'nunique','Quantity':'sum'}).rename(columns={'TotalPrice':'TotalSpend','InvoiceYearMonth':'PurchaseMonths','Quantity':'TotalQuantity'})customer_features['Repurchase']=(customer_features['PurchaseMonths']>1).astype(int)# Train-test splitX=customer_features.drop('Repurchase',axis=1)y=customer_features['Repurchase']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# Model training with parameter combinationsresults=[]forn_estimators,max_depth,class_weightinproduct(n_estimators_options,max_depth_options,class_weight_options):clf=RandomForestClassifier(n_estimators=n_estimators,max_depth=max_depth,class_weight=class_weight,random_state=42)clf.fit(X_train,y_train)accuracy=clf.score(X_test,y_test)results.append((n_estimators,max_depth,class_weight,accuracy))returnresults# Measure total execution timeresults,total_time=time_execution(complete_process)print(f"Total execution time for the entire process:{total_time}seconds")# 2\. Timing the Excel file readingdefread_excel():returnpd.read_excel('Online Retail.xlsx',engine='openpyxl')# Measure time taken to read the Excel file_,read_time=time_execution(read_excel)print(f"Time taken to read the Excel file:{read_time}seconds")# 3\. Timing the model trainingdeftrain_model(X_train,y_train):results=[]forn_estimators,max_depth,class_weightinproduct(n_estimators_options,max_depth_options,class_weight_options):clf=RandomForestClassifier(n_estimators=n_estimators,max_depth=max_depth,class_weight=class_weight,random_state=42)clf.fit(X_train,y_train)accuracy=clf.score(X_test,y_test)results.append((n_estimators,max_depth,class_weight,accuracy))returnresults# Measure time taken to train the model_,train_time=time_execution(train_model,X_train,y_train)print(f"Time taken to train the model:{train_time}seconds")

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6680c96a3ff5a703c1e00b62aa6c96fd.png

作者截图

整个过程需要近 20 秒,其中大约 18 秒用于读取数据文件。


解决方案一:启用 GPU 并设置内存增长

与 CPU 相比,GPU 非常适合处理大型数据集和复杂模型,如深度学习,因为它们支持并行处理。有时,开发者会忘记设置内存增长,这会导致 GPU 在启动时尝试为模型分配所有内存。

那么,内存增长是什么?为什么在使用 GPU 时它如此重要?内存增长是一种机制,允许 GPU 按需增量分配内存,而不是预先保留一大块内存。如果没有设置内存增长,并且模型较大,可能没有足够的可用内存,这可能导致“内存不足”错误。在多个模型同时运行的情况下,一个模型消耗了所有 GPU 内存,阻止其他模型访问 GPU。

简而言之,正确设置内存增长可以启用高效的 GPU 使用,增强灵活性,并提高大数据集和复杂模型训练过程的鲁棒性。在启用 GPU 并设置内存增长后,代码的表现如下:

importtensorflowastffromsklearn.model_selectionimporttrain_test_splitimportpandasaspdfromitertoolsimportproductimporttime# Enable GPU and Set Memory Growthgpus=tf.config.experimental.list_physical_devices('GPU')ifgpus:try:forgpuingpus:tf.config.experimental.set_memory_growth(gpu,True)exceptRuntimeErrorase:print(e)# Function to calculate and print elapsed timedeftime_execution(func,*args,**kwargs):start_time=time.time()result=func(*args,**kwargs)elapsed_time=time.time()-start_timereturnresult,elapsed_time# Read Excel Filedefread_excel():returnpd.read_excel('Online Retail.xlsx',engine='openpyxl')# Complete Process Functiondefcomplete_process():# Load dataset from Excel filedata=read_excel()# Data preprocessingdata=data.dropna(subset=['CustomerID'])data['InvoiceYearMonth']=data['InvoiceDate'].astype('datetime64[ns]').dt.to_period('M')# Feature Engineeringdata['TotalPrice']=data['Quantity']*data['UnitPrice']customer_features=data.groupby('CustomerID').agg({'TotalPrice':'sum','InvoiceYearMonth':'nunique','Quantity':'sum'}).rename(columns={'TotalPrice':'TotalSpend','InvoiceYearMonth':'PurchaseMonths','Quantity':'TotalQuantity'})customer_features['Repurchase']=(customer_features['PurchaseMonths']>1).astype(int)# Train-test splitX=customer_features.drop('Repurchase',axis=1)y=customer_features['Repurchase']X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)# Model training with parameter combinationsresults=[]n_estimators_options=[50,100]max_depth_options=[None,10]class_weight_options=[None,'balanced']forn_estimators,max_depth,class_weightinproduct(n_estimators_options,max_depth_options,class_weight_options):clf=RandomForestClassifier(n_estimators=n_estimators,max_depth=max_depth,class_weight=class_weight,random_state=42)clf.fit(X_train,y_train)accuracy=clf.score(X_test,y_test)results.append((n_estimators,max_depth,class_weight,accuracy))returnresults# Measure total execution timeresults,total_time=time_execution(complete_process)print(f"Total execution time for the entire process:{total_time}seconds")# Measure time taken to read the Excel file_,read_time=time_execution(read_excel)print(f"Time taken to read the Excel file:{read_time}seconds")# Measure time taken to train the modeldeftrain_model(X_train,y_train):results=[]n_estimators_options=[50,100]max_depth_options=[None,10]class_weight_options=[None,'balanced']forn_estimators,max_depth,class_weightinproduct(n_estimators_options,max_depth_options,class_weight_options):clf=RandomForestClassifier(n_estimators=n_estimators,max_depth=max_depth,class_weight=class_weight,random_state=42)clf.fit(X_train,y_train)accuracy=clf.score(X_test,y_test)results.append((n_estimators,max_depth,class_weight,accuracy))returnresults _,train_time=time_execution(train_model,X_train,y_train)print(f"Time taken to train the model:{train_time}seconds")

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/41779e68936315a1f6d72dd9b63bb9d8.png

作者截图

训练模型所需的时间显著从 1.9 秒减少到 0.6 秒。但观察到读取 Excel 文件的时间并没有大幅减少。因此,需要另一种技术来提高加载和处理数据的效率——使用数据管道预取进行磁盘 I/O 优化。


解决方案二:使用数据管道预取进行磁盘 I/O 优化

当读取非常大的数据集时,磁盘输入/输出可能会成为瓶颈。TensorFlow 的tf.dataAPI 通过允许异步操作和并行处理,有效地优化了输入管道,并提高了数据加载和处理的效率。这种解决方案减少数据加载和处理时间的原因在于,它通过最小化读取大型数据集相关的延迟,并通过与并行数据处理对齐,创建了一个从磁盘到处理管道的连续、优化的数据流。使用tf.data加载Online Retail.xlsx数据的更新代码如下:

importtimeimportpandasaspdimporttensorflowastf# Function to calculate and print elapsed timedeftime_execution(func,*args,**kwargs):start_time=time.time()result=func(*args,**kwargs)elapsed_time=time.time()-start_timereturnresult,elapsed_time# Function to load and preprocess dataset using tf.datadefload_data_with_tfdata(file_path,batch_size):# Define a generator function to yield data from the Excel filedefdata_generator():data=pd.read_excel(file_path,engine='openpyxl')for_,rowindata.iterrows():yielddict(row)# Create a tf.data.Dataset from the generatordataset=tf.data.Dataset.from_generator(data_generator,output_signature={col:tf.TensorSpec(shape=(),dtype=tf.float32)forcolindata.columns})# Apply shuffle, batch, and prefetch transformationsdataset=dataset.shuffle(buffer_size=1000).batch(batch_size).prefetch(tf.data.experimental.AUTOTUNE)returndataset# Load and preprocess dataset using tf.data.Datasetfile_path='Online Retail.xlsx'batch_size=32dataset,data_load_time=time_execution(load_data_with_tfdata,file_path,batch_size)print(f"Time taken to load and preprocess data with tf.data:{data_load_time}seconds")

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6cfd76ad7335de0046907d4faec4bb5b.png

作者截图

加载数据所需的时间显著从 18 秒减少到 0.05 秒。

正确定义batch_size是必要的,因为每一步处理的数据大小会影响内存消耗和计算效率。如果没有设置批大小,它可能默认为 1,这会使数据加载和处理或模型训练非常低效。当设置批大小过大或过小时,可能会导致训练效率低下、内存错误、收敛速度变慢或模型性能不佳。


结论

GPU 非常适合处理极其庞大的数据集和高度复杂的模型,但如果没有适当的参数设置,其优势几乎无法发挥。启用 GPU 内存增长优化了 GPU 的使用,并防止了内存错误。使用数据管道预取进行磁盘 I/O 优化显著减少了数据加载和处理时间。这些技术共同为克服日常工作中遇到的挑战提供了实用且影响深远的解决方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/9 0:56:23

如何使用 ONNX 运行 Stable Diffusion

原文:towardsdatascience.com/how-to-run-stable-diffusion-with-onnx-dafd2d29cd14?sourcecollection_archive---------4-----------------------#2024-05-13 解决安装过程中的兼容性问题 | ONNX 用于 NVIDIA GPU | Hugging Face 的 Optimum 库 https://medium.c…

作者头像 李华
网站建设 2026/1/8 23:25:09

NVIDIA官方镜像安全性认证说明:TensorRT篇

NVIDIA官方镜像安全性与TensorRT推理优化实践 在AI模型日益复杂、部署场景愈发多样的今天,如何让一个训练好的神经网络真正“跑得快、稳得住、安心得下”,是每个工程师都绕不开的问题。尤其是在金融、医疗、自动驾驶这类对延迟和可靠性要求极高的领域&a…

作者头像 李华
网站建设 2026/1/9 9:53:31

告别资产丢失!U位管理系统如何让机房管理效率提升300%?

在数字化转型的加速期,数据中心机房已成为企业运营的核心命脉。然而,传统的机房资产管理方式,却常常让运维团队陷入“资产找不到、空间用不好、效率提不高、安全控不住”的困境。据行业统计,因资产定位不准和运维效率低下导致的隐…

作者头像 李华
网站建设 2026/1/7 2:53:26

使用TensorRT进行模型benchmark的标准流程

使用TensorRT进行模型benchmark的标准流程 在AI系统从实验室走向生产环境的过程中,一个常被忽视但至关重要的环节是:模型推理性能到底能不能扛住真实流量? 训练完成的模型精度再高,如果在线上服务中延迟飙升、吞吐不足&#xff…

作者头像 李华
网站建设 2026/1/12 17:08:43

基于TensorRT的跨框架模型统一部署方案

基于TensorRT的跨框架模型统一部署方案 在现代AI系统中,一个令人熟悉的场景是:算法团队用PyTorch训练出高精度的视觉模型,NLP组则基于TensorFlow开发了强大的语义理解模块,而工程团队却为如何将这些“各自为政”的模型高效上线焦头…

作者头像 李华
网站建设 2026/1/12 6:27:26

使用TensorRT优化Diffusion模型采样过程

使用TensorRT优化Diffusion模型采样过程 在当前AIGC(人工智能生成内容)爆发式增长的背景下,用户对图像生成质量的要求越来越高,而背后的扩散模型——如Stable Diffusion、DALLE等——也变得愈发复杂。这些模型往往依赖数十层UNet结…

作者头像 李华