千家信息网

怎么避免编写pandas代码

发表于:2024-11-27 作者:千家信息网编辑
千家信息网最后更新 2024年11月27日,本篇内容主要讲解"怎么避免编写pandas代码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么避免编写pandas代码"吧!设置from platfor
千家信息网最后更新 2024年11月27日怎么避免编写pandas代码

本篇内容主要讲解"怎么避免编写pandas代码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么避免编写pandas代码"吧!

设置

from platform importpython_versionimport numpy as np import pandas as pdnp.random.seed(42) # set the seed tomake examples repeatable

样本数据集

样本数据集包含各个城市的预订信息,是随机的,唯一目的是展示样本。

数据集有三列:

  • id表示唯一的标识

  • city表示预定的城市信息

  • booked perc表示特定时间预定的百分比

数据集有一万条,这使速度改进更加明显。注意,如果代码以正确的pandas方式编写,pandas可以利用DataFrames计算数百万(甚至数十亿)行的统计数据。

size = 10000cities =["paris", "barcelona", "berlin", "newyork"]df = pd.DataFrame(     {"city": np.random.choice(cities,sizesize=size), "booked_perc": np.random.rand(size)} ) df["id"] = df.index.map(str) +"-" + df.city dfdf = df[["id", "city", "booked_perc"]] df.head()

1. 如何避免对数据求和

来自Java世界的灵感,把"多行for循环"应用到了Python。

计算booked perc列的总和,把百分比加起来毫无意义,但无论如何,一起来试试吧,实践出真知。

%%timeitsuma = 0 for _, row in df.iterrows():     suma += row.booked_perc766ms ± 20.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

更符合Python风格的方式来对列求和如下:

%%timeitsum(booked_perc forbooked_perc in df.booked_perc)989 µs ± 18.5 µs per loop (mean ±std. dev. of 7 runs, 1000 loops each)%%timeitdf.booked_perc.sum()92µs ± 2.21 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

正如预期的那样,第一个示例是最慢的——对一万项求和几乎需要1秒。第二个例子的速度之快令人惊讶。

正确的方法是使用pandas对数据进行求和(或对列使用任何其他操作),这是第三个示例——也是最快的!

2. 如何避免过滤数据

尽管在使用pandas之前,笔者已经很熟悉numpy,并使用for循环来过滤数据。求和时,还是可以观察到性能上的差异。

%%timeitsuma = 0 for _, row in df.iterrows():     if row.booked_perc <=0.5:         suma += row.booked_perc831ms ± 25.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%%timeitdf[df.booked_perc<= 0.5].booked_perc.sum()724 µs ± 18.8 µs per loop(mean ± std. dev. of 7 runs, 1000 loops each)

正如预期的一样,第二个例子比第一个例子快很多

如果加入更多的过滤器呢?只需把它们添加到括号里:

%%timeitdf[(df.booked_perc <=0.5) & (df.city == 'new york')].booked_perc.sum()1.55ms ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3. 如何避免访问以前的值

你可能会说:好吧,但是如果需要访问先前某一列的值呢,还是需要一个for循环。你错了!

分别使用和不使用for循环来计算一行到另一行百分数的改变

%%timeitfor i inrange(1, len(df)):     df.loc[i,"perc_change"] =  (df.loc[i].booked_perc- df.loc[i - 1].booked_perc) / df.loc[i- 1].booked_perc7.02 s ± 24.4 ms per loop (mean ± std. dev. of 7runs, 1 loop each)%%timeitdf["perc_change"] = df.booked_perc.pct_change()586µs ± 17.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

同样,第二个例子比第一个使用for循环的例子快得多。

pandas有许多函数可以根据以前的值计算统计数据(例如shift函数对值进行移位)。这些函数接受periods参数,可以在计算中包含以前值的数量。

4. 如何避免使用复杂的函数

有时需要在DataFrame中使用复杂函数(有多个变量的函数)。让我们将从纽约的booking_perc两两相乘,其他设置为0并且把这列命名为sales_factor。

笔者首先想到的是使用iterrows的for循环。

%%timeitfor i, row in df.iterrows():     if row.city =='new york':         df.loc[i, 'sales_factor'] =row.booked_perc * 2     else:         df.loc[i, 'sales_factor'] =03.58 s ± 48.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

一个更好的办法是直接在DataFrame上使用函数。

%%timeitdef calculate_sales_factor(row):     if row.city =='new york':         return row.booked_perc* 2     return 0df['sales_factor'] =df.apply(calculate_sales_factor, axis=1)165 ms ± 2.48 ms per loop(mean ± std. dev. of 7 runs, 10 loops each)

最快的方法是使用pandas过滤器直接计算函数值。

%%timeit df.loc[df.city== 'new york', 'sales_factor'] = df[df.city == 'newyork'].booked_perc * 2 df.sales_factor.fillna(0, inplace=True)3.03 ms ± 85.5 µsper loop (mean ± std. dev. of 7 runs, 100 loops each)

可以看到从第一个例子到最后一个的加速过程。

当解决有3个及3个以上变量的函数时,可以把它分解为多个pandas表达式。这比运用函数更快。

Eg: f(x, a, b) = (a + b) * x df['a_plus_b'] = df['a'] +df['b'] df['f'] = df['a_plus_b'] * df['x']

5. 如何避免对数据进行分组

现在可以看到,在开始使用pandas之前,笔者更多依赖于for循环。至于对数据进行分组,如果充分发挥pandas的优势,可以减少代码行数。

要计算如下数据:

  • 一个城市的平均sales factor

  • 一个城市的首次预定id

%%timeit avg_by_city = {} count_by_city = {} first_booking_by_city = {}for i, row in df.iterrows():     city = row.city     if city in avg_by_city:         avg_by_city[city] += row.sales_factor         count_by_city[city] += 1     else:         avg_by_city[city] = row.sales_factor         count_by_city[city] = 1         first_booking_by_city[city] =row['id']for city, _ in avg_by_city.items():     avg_by_city[city] /=count_by_city[city]878 ms ± 21.4 ms per loop (mean ± std. dev. of 7 runs, 1 loopeach)

Pandas有分组操作所以不必在DataFrame上进行迭代,pandas的分组操作和SQL的GROUP BY语句一样的。

%%timeitdf.groupby('city').sales_factor.mean() df.groupby('city').sales_factor.count() df.groupby('city').id.first()3.05 ms ± 65.3 µs per loop(mean ± std. dev. of 7 runs, 100 loops each)%%timeitdf.groupby("city").agg({"sales_factor":["mean", "count"], "id": "first"})4.5ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

到此,相信大家对"怎么避免编写pandas代码"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

数据 函数 循环 例子 代码 城市 分组 方法 更多 样本 百分 笔者 复杂 最快 一行 信息 内容 变量 多个 方式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北服务器机柜规格尺寸 方舟手游如何登之前玩过的服务器 巴中网络技术哪个好 服务器如何设置端口 广州慧恩互联网科技有限公司 贵州新一代网络技术分类标准 福州臻诚网络技术有限公司 如何设置计算机服务器的入站规则 我的世界国际版怎么进别人服务器 ssm系统如何调用数据库中内容 微信为什么显示服务器不在线 上海豪廷网络技术有限公司招聘 云南智乐互联网络科技有限公司 聊城戴尔服务器零售 medium网络安全教程 数据库各种约束关系 上海运维服务软件开发方案 新基建网络安全加速 公司服务器内容下载 游戏软件开发的职业能力倾向 服务器的状态码 杭州点告网络技术有限 新西兰网络安全管理局 成都学习软件开发哪个好 保障网络安全保护公民 舜宇软件开发加班严重吗 360网络安全评估平台 虚假网络安全系统 软件开发小公司有多少人 剑网三念破服务器
0