【问题标题】:Which is faster pandas.iterrows () or UDF function?pandas.iterrows() 和 UDF 函数哪个更快?
【发布时间】:2021-09-27 20:22:57
【问题描述】:

我有一个疑问。
这两者中哪一个执行得更快?我正在使用 Google Colab
这样,我使用 pandasitrrrow() 循环遍历所有行。 我写的这两个只是作为示例,以了解两者哪个更快。
withColumn 的情况下,如何将其应用于 randomFunction 函数?

这是 UDF:

import string

def randomFunction(text):
    if (text == "Hello"):
       cnt_en += 1
    else:
       cnt_en -= 1
    return cnt_en

这是一个循环循环:

cnt_en = 0
for index, row in pandasDF.iterrows():
  if (text == "Hello"):
       cnt_en += 1
    else:
       cnt_en -= 1
print (cnt_en)

谁能告诉我这两个哪个更快? 我有一个包含 2,500,000 行的数据框。

【问题讨论】:

  • 为什么你不使用 withColumn() df = df.withColumn("col_name", F.col("col_name").cast(T.IntegerType())) -> 这将是方式比上面两个快
  • @dsk 完美!!但是,如果它不是字符串到整数转换(反之亦然)之类的“标准”函数怎么办?例如我刚刚添加到上述问题中的函数?

标签: python pandas pyspark google-colaboratory data-analysis


【解决方案1】:

为了速度,您最好使用矢量化函数并避免显式循环(循环无论如何都会发生,但在编译代码中,而不是作为 Python 函数结束)。这需要根据所需的功能进行一些思考和调整。

例如,您可以将randomFunction() 转换为:

cnt_en = 2 * (df['text'] == 'Hello').sum() - df.shape[0]

为了说明速度差异:

n = 2_500_000 // 100
df = pd.DataFrame({
    'text': np.random.choice('Hi Hello World'.split(), n),
})

def base(df):
    cnt_en = 0
    for _, row in df.iterrows():
        if (row['text'] == "Hello"):
            cnt_en += 1
        else:
            cnt_en -= 1

    return cnt_en

def modified(df):
    return 2 * (df['text'] == 'Hello').sum() - df.shape[0]

t_base = %timeit -o base(df)
# 1.45 s ± 6.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

t_modf = %timeit -o modified(df)
# 1.7 ms ± 994 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

>>> t_base.average // t_modf.average
855.0

加速超过 800 倍。在完整的 250 万行中,modified() 在我的机器上需要 150 毫秒。

旁注:我必须修改您的代码,因为 sn-p 都没有按规定工作。

【讨论】:

    猜你喜欢
    • 2011-12-08
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多