Polars 将性能应用于自定义功能

Qua*_*sto 2 apply pandas python-polars

除了一种情况外,我很享受 Polars 比 Pandas 的显着加速。我是 Polars 的新手,所以这可能只是我的错误用法。无论如何,这里是玩具示例:在单列上,我需要在我的情况下应用自定义函数,它来自parseprobablypeoplehttps://github.com/datamade/probablepeople),但问题是通用的。

Plain pandasapply与 Polars 具有相似的运行时间,但是带有parallel_applyfrom ( https://github.com/nalepae/pandaralel ) 的 pandas 的加速与核心数量成正比。

在我看来,Polars 仅使用单核来实现自定义功能,或者我错过了什么?

如果我正确使用 Polars,也许有可能创建像pandaralellPolars 这样的工具?

!pip install probablepeople
!pip install pandarallel

import pandas as pd
import probablepeople as pp
import polars as pl
from pandarallel import pandarallel

AMOUNT = 1000_000
#Pandas:
df = pd.DataFrame({'a': ["Mr. Joe Smith"]})
df = df.loc[df.index.repeat(AMOUNT)].reset_index(drop=True)

df['b'] = df['a'].apply(pp.parse)

#Pandarallel:
pandarallel.initialize(progress_bar=True)
df['b_multi'] = df['a'].parallel_apply(pp.parse)

#Polars:
dfp = pl.DataFrame({'a': ["Mr. Joe Smith"]})
dfp = dfp.select(pl.all().repeat_by(AMOUNT).explode())

dfp = dfp.with_columns(pl.col('a').apply(pp.parse).alias('b'))


Run Code Online (Sandbox Code Playgroud)

jqu*_*ous 6

pandarallel使用多处理。

\n

您还可以对极坐标使用多重处理。

\n

我们使用带有默认设置的multiprocessing.pool.Pool.imap作为示例。

\n\n
import multiprocessing\nimport polars as pl\nimport probablepeople as pp\nfrom   pip._vendor.rich.progress import track\n\ndef parallel_apply(function, column):\n    with multiprocessing.get_context("spawn").Pool() as pool:\n        return pl.Series(pool.imap(function, track(column)))\n\nif __name__ == "__main__":\n\n    df = pl.DataFrame({\n       "name": ["Mr. Joe Smith", "Mrs. I & II Alice Random"]\n    })\n\n    df = df.with_columns(pp = \n       pl.col("name").map_batches(lambda col: parallel_apply(pp.parse, col))\n    )\n\n    print(df)\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • .map_batches()用于将完整列传递给函数。

    \n
  • \n
  • parallel_apply该列与要在池中执行的 Python 函数一起传递,例如pp.parse

    \n
  • \n
  • rich.progress.track()(也与 捆绑在一起pip)用于进度条。

    \n
  • \n
\n
Working... \xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81 100% 0:00:00\nshape: (2, 2)\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 name                     \xe2\x94\x86 pp                                \xe2\x94\x82\n\xe2\x94\x82 ---                      \xe2\x94\x86 ---                               \xe2\x94\x82\n\xe2\x94\x82 str                      \xe2\x94\x86 list[list[str]]                   \xe2\x94\x82\n\xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1\n\xe2\x94\x82 Mr. Joe Smith            \xe2\x94\x86 [["Mr.", "PrefixMarital"], ["Joe\xe2\x80\xa6 \xe2\x94\x82\n\xe2\x94\x82 Mrs. I & II Alice Random \xe2\x94\x86 [["Mrs.", "PrefixMarital"], ["I"\xe2\x80\xa6 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n
\n

表现

\n

作为基本比较,创建行1_000_000数据框 - 我得到以下运行时:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
多重处理期间
是的1分23秒
5平方米
\n