什么是python编程例子_案例详解:优化Python编程的4个妙招

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

9f510fb30f2442a754b8fb055842324ed01302e6.png?token=4ea7bf38d7b51337f95eac5bdd04e52b&s=51B3C87E04242D15370ED11A0300E00D

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

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

什么是最优化?

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

问题是这样的:

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

11385343fbf2b2117142e6444781fa3d0cd78e57.png?token=059b3214dd70674296f9801be7dfb926

4a36acaf2edda3cc2c208dc888e8a604203f921c.png?token=9f8eb3556c170912765acba37d301d6a&s=9E94ED02C5E05D031E6590DB0300B033

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

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

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

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

c8177f3e6709c93d30776dec163c67d9d100542e.png?token=9a4044911dbfd47cc7627664fa094143&s=E9C293466DA6AF7014D5D10B0300F0C3

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

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

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

数组总大小为100000。

需求总数为50000。

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

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

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

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

eaf81a4c510fd9f944dbf2f4af2c4b2f2934a462.png?token=ae689ec33b41bd6a98c40ae69a59960e

b2de9c82d158ccbf0a7b9b6690d9233bb03541a9.png?token=8eccc3157ca29e88f73b874a97e577b4&s=1C90CD1083F45D8A626BDCDC0300D0BA

30adcbef76094b364920498929cde3dc8d109d2f.png?token=766e0bd37f5a0ad9aaafa395d9b0f47f

大家能理解这里的做法吗?这样只需一次计算就得到了同样的城市距离!这一方法最棒的地方就是,不管指数间的差距是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()

d058ccbf6c81800a5c2082583834acff838b47a1.png?token=67ef5e5aef7f751f324ffad6cd412115&s=1110EC33C5F244234AD551CA0300E0B2

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

91ef76c6a7efce1bc109f48426506cdbb48f6560.png?token=bdc684f3b38e80c612f95c0297f853ea&s=ED8AFC1B514FC4EE0AF5A1DA0300D0B3

现在,假设只需要排名前五位的城市,其他城市替换为“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()

6159252dd42a2834c0f2343ad2b456ef15cebfb6.png?token=4b451f9e092e9f92e1df7d06305678d2&s=E500FC1A03504DCA00DCA1DA030010B3

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

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

caef76094b36acaf49014552f6d8121500e99c46.png?token=8dc9482302ab8b5600cdfc9b99db175c

%%time

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

77c6a7efce1b9d16e667ea697cdf2b8a8c546418.png?token=81d96f86d138fd028dd567a1f413ee4e

%%time

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

answer = pool.map(countDivisors,random_data)

pool.close()

pool.join()

b17eca8065380cd720b0188f2b45323159828129.png?token=6efcc9a80fd836879d897d2556538579

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

f9198618367adab4f3d4057200d52c198701e486.jpeg?token=5b02c68bf9eda59f7056d3fb08cb5eb1

留言 点赞 关注

我们一起分享AI学习与发展的干货

如需转载,请后台留言,遵守转载规范

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值