高级-Pandas-技巧-数据处理和性能优化

高级 Pandas 技巧:数据处理和性能优化

原文:towardsdatascience.com/advanced-pandas-techniques-for-data-processing-and-performance-23f9026d21f5/

由 Weichao Deng 在 Unsplash 上拍摄的照片

Weichao DengUnsplash 拍摄的照片

如果你在处理数据,Pandas 是一个必不可少的 Python 库。无论你是程序员、数据科学家、分析师还是研究人员,你都会发现它使得处理结构化数据变得容易得多。它为你提供了灵活直观的工具,可以处理甚至是最复杂的数据集。

当你深入 Pandas 时,掌握它将显著提高你的生产力和简化你的工作流程。我们将探讨 7 个基本技巧,这些技巧将帮助你充分利用库的潜力,并更有效地应对数据挑战。

为了说明以下技巧,我将使用 Kaggle 的 Airbnb 列表数据集。你可以从这里 获取数据集(许可:CC0:公共领域) 该数据集包含三个 CSV 文件:calendar.csvlistings.csvreviews.csv。这些文件分别包含关于物业可用性、详细列表属性和用户评论的信息。通过处理真实世界的数据,我将展示 Pandas 如何高效地处理和分析在数据科学项目中常见的大型、多文件数据集。

1. 分块读取数据

我们经常遇到数据大小超过我们可用内存(RAM)的情况。在这种情况下,从文件中分块读取数据是一个好主意,这样系统就不会耗尽内存。这种方法允许你增量处理数据,减少内存使用,并可能加快你的工作流程。

2. 在使用 apply() 函数时渲染进度条

我一直是 [tqdm](https://pypi.org/project/tqdm/) 库的用户。对于那些不了解 tqdm 的人来说,它是显示迭代操作进度条的流行选择。它提供了一种无缝的方式来跟踪循环和其他可迭代过程的状态,这在处理大型数据集时尤其有帮助。然而,我在将 tqdm 应用于 Pandas 的 apply() 函数时遇到了挑战,这些函数通常用于在 DataFrame 的列或行上执行元素级操作。

令我高兴的是,我发现tqdm实际上支持 Pandas 的apply()方法。只需在您的代码中进行小小的修改。您只需将标准的apply()函数替换为progress_apply()。这将自动显示进度条,让您对apply()操作的执行情况有宝贵的了解。在此之前,请确保导入tqdm并在其下方添加一行代码以将其与 pandas 集成。

为了演示,让我们回到listings.csv数据集,并将last_review列从string类型转换为datetime类型。我将使用progress_apply函数,这将创建一个进度条。

如果您没有安装tqdm,可以使用以下命令进行安装:

pip3 install tqdm

单元格末尾显示进度条(作者截图)

单元格末尾显示进度条(作者截图)

3. 使用apply()result_type="expand"轻松在 Pandas 中填充多个列

在使用apply函数时,我经常遇到需要从函数中同时返回多个值并将这些值存储在单独列中的场景。那时我发现result_type="expand"参数将帮助我做到这一点。

这节省了我很多时间!我不再需要创建单独的函数并遍历同一组值,只是为了将它们存储在单独的列中。我只需创建一个函数并返回多个值。

在下面的示例中,我演示了同样的方法。我返回两个值——基于审查日期的日期和月份名称。然后这些值分别同时填充到DayMonth列中。

同时填充日期和月份列(作者截图)

日期和月份列同时填充(作者截图)

4. 并行处理 DataFrame

我经常遇到某些过程需要太长时间才能完成的情况。当 DataFrame 有数百万行,并且您需要遍历每一行以提取某些信息时,这会变得非常慢。

这是我使用多进程模块的地方。我将 DataFrames(使用np.array_split())分割成多个块(取决于系统中的核心数),并并行处理 DataFrame 的每个块。这在系统具有多个核心的情况下尤其有用,因为大多数现代系统都具备这种能力。

一旦处理完数据块并获取到每个数据块所需的输出,就可以将其连接回单个 DataFrame。

让我们使用这个评论数据集。它包含来自不同用户的超过 480k 条评论。

为了演示目的,我们将创建一个函数来模拟评论情感预测所需的时间,假设每个预测需要 0.1 秒。

串行处理(作者截图)

串行处理(作者截图)

如您所见,如果我们逐个进行预测,将需要超过 13 小时!

让我们加快这个速度。首先,让我们将评论数据框拆分成多个批次,以便每个批次由不同的核心处理。然后我们可以创建一个多进程池来在多个核心上分配计算。

并行处理(作者截图)

并行处理(作者截图)

通过使用多进程,我们已经将所需的预测时间从超过 13 小时降低到不到 13 分钟!

每个批次包含 7521 条评论,总共有 64 个批次。在这种情况下,我能够将 n_cores 设置得比系统实际的核心数还要多。这是因为当执行 time.sleep(0.1) 时,CPU 保持空闲,每个进程会交错执行其他进程。如果你的进程是 CPU 密集型的,建议将 n_cores 设置得小于系统实际的核心数。

5. 使用 merge() 和 indicator=True 进行复杂合并

合并是处理数据的人员执行的一个相当常见的操作。然而,有时如果合并过程中丢失了任何特定的数据点,理解起来可能会相当复杂。这可能是由于许多原因造成的——最糟糕的是,数据格式不正确或数据有误。

这就是 indicator=True 参数派上用场的地方。当你启用此参数时,它创建了一个名为 _merge 的新列,可以根据执行合并操作的类型表示三种不同的场景。

  1. _leftonly – 表示该行的键仅存在于左侧数据框中,并且在右侧数据框中找不到匹配项

  2. _rightonly – 表示该行的键仅存在于右侧数据框中,并且在左侧数据框中找不到匹配项

  3. both – 表示该行的键存在于两个数据框中,并且数据已成功合并。

这些值也可以在数据操作任务中作为过滤器使用。

在下面的示例中,我将执行评论和列表数据框之间的外部合并。

我正在使用参数 indicator=True 进行外部合并以识别哪些列表没有评论/缺失评论。理想情况下,将 _merge 参数设置为 _"leftonly" 的列表将缺少评论。

merged_df = listings.merge(
    reviews,
    left_on="id",
    right_on="listing_id",
    how="outer",
    indicator=True
)
merged_df.shape

有 841 个无评论的列表(作者截图)

有 841 个无评论的列表(作者截图)

下面是一些无评论的列表示例

无评论的列表示例(作者截图)

无评论的列表示例(作者截图)

6. 使用 pd.cut() 将数据分段到价格区间

pd.cut() 是一个强大的函数,当需要将数据分割成多个区间时可以使用。它还可以作为将连续值转换为分类值的一种方式。

下面将演示一个这样的场景。我们将对每个列表的价格进行分割,将其划分到多个价格区间(区间)中。

我们可以设置预定的价格区间数量 – "$0 – $100", "$101 – $250", "$251 – $500", "$500 – $1000", 以及 "$1000+"。

# Create bins and label for each bin
bins = [0, 100, 250, 500, 1000, float('inf')]
labels = ["$0 - $100", "$101 - $250", "$251 - $500", "$500 - $1000", "$1000+"]

listings["price_bucket"] = pd.cut(listings["price"], bins=bins, labels=labels)

请注意,这里的标签数量(5)比区间数量(6)少一个。这是因为区间中的前两个值属于第一个标签。

价格区间内列表的拆分(作者截图)

价格区间内列表的拆分(作者截图)

我们可以看到,大多数列表(3400 个)位于$101–$250 的范围内,而$1000+范围内的列表数量最少(29 个)。

7. 价格和房间类型交叉分析

使用上述数据,我们可以进一步进行一步,在价格区间和那些价格区间的可用房间类型之间执行交叉分析。

这就是 pd.crosstab() 发挥作用的地方。它可以用来在 price_bucketroom_type 之间执行简单的交叉分析。

room_type_breakup = pd.crosstab(
    listings["price_bucket"],
    listings["room_type"],
    margins=True  # This will add the row and column totals
)

每个价格区间的房间类型分布截图(作者截图)

每个价格区间的房间类型拆分(作者截图)

上面的截图显示了不同价格区间内房间类型的分布。最后一行和列将是行和列总数的总和。如果不需要,请设置 margins=False


到现在为止,你已经学习了几个强大的 Pandas 技巧,这些技巧将显著提高你的数据处理工作流程。从使用分块读取管理大型数据集到通过并行处理加快操作,这些高级方法将帮助你更有效地处理复杂的数据任务。

如果你最近发现了任何其他有趣的技巧,这些技巧提高了你的工作流程,或者如果你找到了处理上述技巧的更有效的方法,请务必告诉我!

posted @ 2026-03-27 10:25  布客飞龙III  阅读(18)  评论(0)    收藏  举报