您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

让你的Pandas代码快得离谱的两个技巧

时间:2024-01-19 16:27:58  来源:微信公众号  作者:郭小喵玩AI

如果你曾经使用过Pandas处理表格数据,你可能会熟悉导入数据、清洗和转换的过程,然后将其用作模型的输入。然而,当你需要扩展和将代码投入生产时,你的Pandas管道很可能开始崩溃并运行缓慢。在这篇文章中,笔者将分享2个技巧,帮助你让Pandas代码快得离谱,提升数据处理效率并避免常见的陷阱。

技巧1:矢量化操作

在Pandas中,矢量化操作是一种强大的工具,它可以用一种更简洁和高效的方式处理整个数据框的列,而不是逐行循环。

它是如何工作的?

广播是矢量化操作的一个关键要素,它允许您直观地操作具有不同形状的对象。

eg1: 具有3个元素的数组a与标量b相乘,得到与Source形状相同的数组。

eg2: 在进行加法运算时,将形状为(4,1)的数组a与形状为(3,)的数组b相加,结果会得到一个形状为(4,3)的数组。

关于这一点已经有很多文章,并且在深度学习中,大规模的矩阵乘法是非常常见的。在本文中,我们将利用两个简短的例子上进行讨论。

首先,假设您想要计算给定整数在列中出现的次数。以下是 2 种可能的方法。

"""
计算DataFrame X 中 "column_1" 列中等于目标值 target 的元素个数。

参数:
X: DataFrame,包含要计算的列 "column_1"。
target: int,目标值。

返回值:
int,等于目标值 target 的元素个数。
"""
# 使用循环计数
def count_loop(X, target: int) -> int:
    return sum(x == target for x in X["column_1"])

# 使用矢量化操作计数
def count_vectorized(X, target: int) -> int:
    return (X["column_1"] == target).sum()

现在假设有一个DataFrame带有日期列并希望将其偏移给定的天数。使用矢量化操作计算如下:

def offset_loop(X, days: int) -> pd.DataFrame:
        d = pd.Timedelta(days=days)
    X["column_const"] = [x + d for x in X["column_10"]]
    return X

def offset_vectorized(X, days: int) -> pd.DataFrame:
    X["column_const"] = X["column_10"] + pd.Timedelta(days=days)
    return X

技巧2:迭代

「for循环」

第一个也是最直观的迭代方法是使用Python/ target=_blank class=infotextkey>Python for循环。

def loop(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    res = []
    i_remove_col = df.columns.get_loc(remove_col)
    i_words_to_remove_col = df.columns.get_loc(words_to_remove_col)
    for i_row in range(df.shape[0]):
        res.Append(
            remove_words(
                df.iat[i_row, i_remove_col], df.iat[i_row, i_words_to_remove_col]
            )
        )
    return result

「apply」

def apply(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return df.apply(
        func=lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1
    ).tolist()

在 df.apply 的每次迭代中,提供的可调用函数获取一个 Series,其索引为 df.columns,其值是行的。这意味着 pandas 必须在每个循环中生成该序列,这是昂贵的。为了降低成本,最好对您知道将使用的 df 子集调用 apply,如下所示:

def apply_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return df[[remove_col, words_to_remove_col]].apply(
        func=lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1
    )

「列表组合+itertuples」

使用itertuples与列表相结合进行迭代肯定会更好。itertuples生成带有行数据的(命名)元组。

def itertuples_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return [
        remove_words(x[0], x[1])
        for x in df[[remove_col, words_to_remove_col]].itertuples(
            index=False, name=None
        )
    ]

「列表组合+zip」

zip接受可迭代对象并生成元组,其中第i个元组按顺序包含所有给定可迭代对象的第i个元素。

def zip_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return [remove_words(x, y) for x, y in zip(df[remove_col], df[words_to_remove_col])]

「列表组合+to_dict」

def to_dict_only_used_columns(df: pd.DataFrame) -> list[str]:
        return [
            remove_words(row[remove_col], row[words_to_remove_col])
            for row in df[[remove_col, words_to_remove_col]].to_dict(orient="records")
        ]

「缓存」

除了我们讨论的迭代技术之外,另外两种方法可以帮助提高代码的性能:缓存和并行化。如果使用相同的参数多次调用 pandas 函数,缓存会特别有用。例如,如果remove_words应用于具有许多重复值的数据集,您可以使用它functools.lru_cache来存储函数的结果并避免每次都重新计算它们。要使用lru_cache,只需将@lru_cache装饰器添加到 的声明中remove_words,然后使用您首选的迭代方法将该函数应用于您的数据集。这可以显着提高代码的速度和效率。以下面的代码为例:

@lru_cache
def remove_words(...):
    ... # Same implementation as before

def zip_only_used_cols_cached(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return [remove_words(x, y) for x, y in zip(df[remove_col], df[words_to_remove_col])]

添加此装饰器会生成一个函数,该函数会“记住”之前遇到的输入的输出,从而无需再次运行所有代码。

「并行化」

最后一张王牌是使用 pandarallel 跨多个独立的 df 块并行化我们的函数调用。该工具易于使用:您只需导入并初始化它,然后将所有 .applys 更改为 .parallel_applys。

from pandarallel import pandarallel
pandarallel.initialize(nb_workers=min(os.cpu_count(), 12))

def parapply_only_used_cols(df: pd.DataFrame, remove_col: str, words_to_remove_col: str) -> list[str]:
    return df[[remove_col, words_to_remove_col]].parallel_apply(
        lambda x: remove_words(x[remove_col], x[words_to_remove_col]), axis=1
    )


Tags:Pandas   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除。
▌相关推荐
让你的Pandas代码快得离谱的两个技巧
如果你曾经使用过Pandas处理表格数据,你可能会熟悉导入数据、清洗和转换的过程,然后将其用作模型的输入。然而,当你需要扩展和将代码投入生产时,你的Pandas管道很可能开始崩溃并...【详细内容】
2024-01-19  Tags: Pandas  点击:(0)  评论:(0)  加入收藏
Pandas的魅力:从数据处理到机器学习
Part 01、 Series和DataFrame:Pandas的核心Pandas的两个主要数据结构是Series和DataFrame。Series是一维标记数组,类似于Python中的列表。而DataFrame是二维标记数据结构,类似...【详细内容】
2023-12-18  Tags: Pandas  点击:(41)  评论:(0)  加入收藏
Python 数据处理,Pandas 使用方式的变局
前段时间在公司技术分享会上,同事介绍了目前市面上关于自动生成 pandas 代码的工具库。我们也尝试把这些工具库引入到工作流程中。经过一段时间的实践,最终还是觉得不适合,不再...【详细内容】
2023-12-12  Tags: Pandas  点击:(57)  评论:(0)  加入收藏
一个闪电般快速的 DataFrame 处理库,完美替代 Pandas
众所周知,SQL和Pandas是数据科学领域常用工具,精通这两大工具对数据科学家来说极有价值。而最近,又有一个新的工具库——「Polars」也开始受到青睐。Polars简介Polar...【详细内容】
2023-12-11  Tags: Pandas  点击:(56)  评论:(0)  加入收藏
四个解决特定的任务的Pandas高效代码
在本文中,我将分享4个在一行代码中完成的Pandas操作。这些操作可以有效地解决特定的任务,并以一种好的方式给出结果。从列表中创建字典我有一份商品清单,我想看看它们的分布情...【详细内容】
2023-12-06  Tags: Pandas  点击:(77)  评论:(0)  加入收藏
Python Pandas数据预处理:你知道数据标准化吗?
数据预处理包括以下几个方面: 缺失值处理 数据格式化 数据规范化 数据标准化 数据分箱(分组)标准化经常容易与规范化混淆,但它们指的是不同的东西。规范化涉及将不同比例的度量...【详细内容】
2023-11-27  Tags: Pandas  点击:(75)  评论:(0)  加入收藏
如何用Python的pandas库函数重命名列名
题目DataFrame students+-------------+--------+| Column Name | Type |+-------------+--------+| id | int || first | object || last | ob...【详细内容】
2023-10-31  Tags: Pandas  点击:(199)  评论:(0)  加入收藏
Python数据分析库 Pandas,数据处理与分析的得力助手!
Python的Pandas库(Python Data Analysis Library)是数据科学家和分析师的得力助手,它提供了强大的数据处理和分析工具,使得数据的导入、清洗、转换和分析变得更加高效和便捷。本...【详细内容】
2023-10-20  Tags: Pandas  点击:(83)  评论:(0)  加入收藏
使用Pandas进行时间重采样,充分挖掘数据价值
一、简介时间序列数据蕴含着很大价值,通过重采样技术可以提升原始数据的表现形式。无论你是数据科学家、分析师,还是对数据挖掘感兴趣,都可以从本文学习方法和工具,提升数据可视...【详细内容】
2023-10-17  Tags: Pandas  点击:(225)  评论:(0)  加入收藏
向量化操作简介和Pandas、Numpy示例
Pandas是一种流行的用于数据操作的Python库,它提供了一种称为“向量化”的强大技术可以有效地将操作应用于整个列或数据系列,从而消除了显式循环的需要。在本文中,我们将探讨什...【详细内容】
2023-10-16  Tags: Pandas  点击:(168)  评论:(0)  加入收藏
▌简易百科推荐
让你的Pandas代码快得离谱的两个技巧
如果你曾经使用过Pandas处理表格数据,你可能会熟悉导入数据、清洗和转换的过程,然后将其用作模型的输入。然而,当你需要扩展和将代码投入生产时,你的Pandas管道很可能开始崩溃并...【详细内容】
2024-01-19  郭小喵玩AI  微信公众号  Tags:Pandas   点击:(0)  评论:(0)  加入收藏
未来世界的12个软件开发预测
译者 | 李睿审校 | 重楼预测软件开发的未来趋势通常是一件困难的事情。因为人们总是期望软件开发领域中的新兴趋势和频繁的变化能够满足市场不断增长的期望。这样的趋势也将...【详细内容】
2024-01-15    51CTO  Tags:软件开发   点击:(6)  评论:(0)  加入收藏
什么是 DevOps?解读 IT 文化革命的目的和重要性
DevOps 将运维和开发相结合以提供持续的软件改进,可以降低复杂性并提高应用程序输出。 什么是 DevOps?DevOps 是组织用来创建和交付应用程序和服务的灵活实践和流程的集合,通过...【详细内容】
2024-01-12  35岁职场危机  今日头条  Tags:DevOps   点击:(5)  评论:(0)  加入收藏
深入理解与应用多线程技术
如果synchronized​作用于代码块,反编译可以看到两个指令:monitorenter、monitorexit,JVM​使用monitorenter和monitorexit​两个指令实现同步;如果作用synchronized​作用于方...【详细内容】
2024-01-09  一安未来  微信公众号  Tags:多线程技术   点击:(10)  评论:(0)  加入收藏
浅析五种 React 组件设计模式
作为一名 React 开发者,你可能会面临下面几个问题: 如何构建一个高复用度性的组件,使其适应不同的业务场景? 如何构建一个具有简单 API的组件,使其易于使用? 如何构建一个在 UI 和...【详细内容】
2024-01-09  政采云技术  微信公众号  Tags:   点击:(8)  评论:(0)  加入收藏
构建 Web API 的两种流行选择:REST vs GraphQL
在 RESTful 和 GraphQL API 之间的选择取决于您的具体用例。RESTful API 适用于需要高可伸缩性的简单应用程序,而 GraphQL 则适用于具有不同数据需求的复杂应用程序。简介RES...【详细内容】
2024-01-09  小技术君  微信公众号  Tags:Web API   点击:(11)  评论:(0)  加入收藏
深入浅出SSH隧道穿透
SSH(Secure Shell)是一种常用的远程登录和文件传输协议,而SSH隧道穿透是SSH协议的一个强大功能。通过SSH隧道,我们可以在两个主机之间建立一个加密的通道,实现安全传输数据和访问...【详细内容】
2024-01-09  科学随想录    Tags:SSH   点击:(8)  评论:(0)  加入收藏
绕过用户模式EDR Hook原理及思路
1.什么是系统调用系统调用是从用户模式过渡到内核模式的标准方式。它们是现代版的软件中断,速度更快。系统调用接口极其复杂,但由于大部分内容与我们的工作无关,我只想做一个较...【详细内容】
2024-01-04  二进制空间安全  微信公众号  Tags:EDR Hook   点击:(13)  评论:(0)  加入收藏
为什么只有Unicode是不够的,UTF-8如何解决编码问题?
UnicodeUnicode是一种字符编码标准,它为世界上几乎所有的文字和符号分配了唯一的数字编码。这使得不同的计算机系统和软件能够正确地显示和处理各种语言的文字。Unicode采用1...【详细内容】
2024-01-04  沐雨花飞蝶  微信公众号  Tags:编码   点击:(11)  评论:(0)  加入收藏
Vanilla Design,新一代 React UI 库
这几天做需求,一堆 UI 库实在是不知道选哪个,各种角色的同事争论不休;还总有新轮子冒出来,所以我来插一脚,并借此来领悟写代码的哲学:The best way to write secure and reliable...【详细内容】
2024-01-04  互联网高级架构师  今日头条  Tags:UI 库   点击:(6)  评论:(0)  加入收藏
站内最新
站内热门
站内头条