案例详解:优化Python编程的4个妙招

559 篇文章 5 订阅

全文共3510字,预计学习时长7分钟

作为数据科学家,敲出最优的Python代码非常非常重要。别无他法,杂乱低效的代码笔记本会消耗你的时间,也会浪费大量项目资金。经验丰富的数据科学家和专业人士都很清楚,这样是没办法和客户合作的。

本文将列出4个可行的Python代码优化方法,以便大家日后应用到自己的数据科学项目中。

什么是最优化?

首先来看一个直观的例子,然后定义什么是最优化。

问题是这样的:

假设有一个数组,其中每个指数代表一个城市,指数的值代表该城市和下一个城市之间的距离。已知两个指数,求这两个指数间的距离。简单来讲,就是求任意两个指数间的总值。

指数

0

1

2

3

4

5

城市

A

B

C

D

E

F

距离

15(A-B)

20(B-C)

6(C-D)

10(D-E)

5(E-F)

-

 

大家肯定首先会想到这里可以用for循环。但是如果一共有十几万个城市,每秒会收到五万多个查询需求呢?这种情况下,for循环还是这个问题的最优解吗?

不是了吧。此时就该挥动优化代码的仙女棒了。

代码最优化,简单来讲,就是在保证结果正确的前提下尽可能减少执行任务的运算量。

来算算for循环完成任务所需的运算量吧:

首先计算出上面数组中指数1和3代表的城市间的距离。

指数1和3代表城市之间的距离=(0+20+6+10)=36=>3次算术运算。

如果数组大小为100000,需求数量为50000呢?

数组总大小为100000。

需求总数为50000。

假设两指数间的平均差异为1000。

完成该任务的算术运算总量近似值为50000*1000=50000000

这个数量非常庞大。如果数据和查询量不断增加,for循环将会花费更多的时间。如果想减少计算量,同时又想得到正确的结果,应该采取什么优化方法呢?

这里,使用前缀数组来计算距离是一种可能的优化方案。它是这样运算的:

大家能理解这里的做法吗?这样只需一次计算就得到了同样的城市距离!这一方法最棒的地方就是,不管指数间的差距是1还是100000,只需一次计算就能算出任意两个指数间的距离。是不是很神奇?

我们用10万的数组和5万查询量创建了一个样本数据集。在下面的在线编程窗口中比较两种方法所需的时间。

注意:数据集总查询量为5万,你可以改变execute_queries参数,执行不超过5万的任一查询数量,看看每种方法完成任务所花费的时间。

最优化不仅能节省时间,大大加快完成速度,还能节省计算能力!

这些要怎么应用于数据科学项目呢?大家可能已经注意到了,很多时候需要对大量数据点进行相同查询,尤其是数据预处理阶段。

所以,在编程中运用最优化方法,从而尽可能快速有效地完成任务至关重要。以下就来分享几个提升优化Python代码的方法。

1. Pandas.apply() – 特征工程瑰宝

Pandas 库已经非常优化了,但是大部分人都没有发挥它的最大作用。想想它一般会用于数据科学项目中的哪些地方。

一般首先能想到的就是特征工程,即用已有特征创造新特征。其中最高效的方法之一就是Pandas.apply(),即Pandas中的apply函数。

在Pandas.apply()中,可以传递用户定义功能并将其应用到Pandas Series的所有数据点中。这个函数是Pandas库最好的扩展功能之一,它能根据所需条件分隔数据。之后便能将其有效应用到数据处理任务中。

试着用推特的情感分析数据来计算每条推文的字数吧。可以使用dataframe iterrows函数、NumPy程序库和apply函数等方法,再在下面的在线编程窗口中进行比较。

数据集可在此处下载:https://datahack.analyticsvidhya.com/contest/practice-problem-twitter-sentiment-analysis/?utm_source=blog&utm_medium=4-methods-optimize-python-code-data-science

apply比iterrows函数快多了。它的性能和NumPy类似,但是却更加灵活。

阅读更多文档:https://datahack.analyticsvidhya.com/contest/practice-problem-twitter-sentiment-analysis/?utm_source=blog&utm_medium=4-methods-optimize-python-code-data-science

 

2. Pandas.DataFrame.loc – Python数据操作绝妙技巧

所有和数据处理打交道的数据科学家(差不多所有人了!)都应该学会这个方法。

很多时候,数据科学家需要根据一些条件更新数据集中某列的某些值。Pandas.DataFrame.loc就是此类问题最优的解决方法。

试试用它来解决下面这个问题吧。

数据集可在此处下载:https://drive.google.com/file/d/1VwXDA27zgx5jIq8C7NQW0A5rtE95e3XI/view?usp=sharing

# importing libraries

import pandas as pd

data = pd.read_csv('school.csv')

data.head()

检查“City”变量的值计算:

现在,假设只需要排名前五位的城市,其他城市替换为“Others”,试着做一下:

# save the top cities in a list

top_cities = ['Brooklyn','Bronx','Manhattan','Jamaica','Long Island City']

# use loc to update the target

data.loc[(data.City.isin(top_cities) == False),'City'] = 'Others'

# city value counts

data.City.value_counts()

看到更新这些值有多简单了吗?完成此类数据操作任务最好的方法就是它了。

3. Python函数向量化

另一种解决缓慢循环的方法就是将函数向量化。这意味着新建函数会应用于输入列表,并返回结果数组。在Python中使用向量化能至少迭代两次,从而加速计算。

事实上,这样不仅能加速代码运算,还能让代码更加简洁清晰。

4. Python多重处理

多重处理能使系统同时支持一个以上的处理器。

此处将数据处理分成多个任务,让它们各自独立运行。处理庞大的数据集时,即使是apply函数也显得有些迟缓。

所以,来看看Python中的多重处理库怎么大显神通吧。

先随机创建一百万个点,然后计算每个点的除数。比较apply函数和多重处理完成这一任务的性能:

# importing required libraries

import pandas as pd

import math

import multiprocessing as mp

from random import randint

# function to calculate the number of divisors

def countDivisors(n) :

count = 0

for i in range(1, (int)(math.sqrt(n)) + 1) :

if (n % i == 0) :

if (n / i == i) :

count = count + 1

else :

count = count + 2

return count

# create random data

random_data = [randint(10,1000) for i in range(1,1000001)]

data = pd.DataFrame({'Number' : random_data })

data.shape

%%time

data['Number_of_divisor'] = data.Number.apply(countDivisors)

%%time

pool = mp.Pool(processes = (mp.cpu_count() - 1))

answer = pool.map(countDivisors,random_data)

pool.close()

pool.join()

这个问题中,多重处理生成的输出比apply函数快了13倍。它的性能可能会随着硬件系统不同而有所变化,但是必定会提升性能。

留言 点赞 关注

我们一起分享AI学习与发展的干货
欢迎关注全平台AI垂类自媒体 “读芯术”

(添加小编微信:dxsxbb,加入读者圈,一起讨论最新鲜的人工智能科技哦~)

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值