【问题标题】:Python RecursionError : Simple operation crashes with Pandas.eval()Python RecursionError : Pandas.eval() 的简单操作崩溃
【发布时间】:2018-11-16 10:55:28
【问题描述】:

我刚刚阅读并为我的Pandas 相关需求对these newly found optimization functions 感到兴奋而流口水。根据这本书:

DataFrame.eval() 方法允许使用列对表达式进行更简洁的评估:

result3 = df.eval('(A + B) / (C - 1)') 
np.allclose(result1, result3)

是的

以我为例:

我的数据框包含大约 42000 条记录和 28 列。其中两个是DateHeure,它们是字符串。

我的目标:将两列合并为一列。我可以用这段代码轻松完成:df_exade_light["Date"]+df_exade_light["Heure"],在其上应用%timeit 返回

每个循环 6.07 ms ± 219 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

但由于某种原因,df.eval('Date + Heure') 返回一个:

RecursionError: 超出最大递归深度

更重要的是,我应用了this thread 中的解决方案来提高允许的堆栈深度,但内核只是崩溃了。

这是什么原因?我做错了吗?


这个问题可以用这段代码重现:

import pandas as pd

df = pd.DataFrame({'A': ['X','Y'],
                   'B': ['U','V']})

df.eval('A+B')

【问题讨论】:

    标签: python python-3.x pandas eval numexpr


    【解决方案1】:

    您的可复制示例中的问题是您有 string。在您提供的关于High-Performance Pandas: eval() and query() 的链接中,所有示例都带有float(或int)。

    使其适用于您的示例的一种方法是使用 python 作为引擎:

    df.eval('A+B',engine='python')
    

    默认情况下,eval中使用的引擎是'numexpr',根据documentation,这个引擎使用同名库NumExpr,这是一个NumPy的快速数值表达式求值器。虽然在上一个链接中,提供了一个带有字符串的示例,但它没有使用 + 操作。如果您使用df.eval('A==B'),它可以工作,与其他比较运算符相同,但不是df.eval('A+B')。您可以找到更多信息 there,但对于 string,除了使用 engine='python' 之外,它似乎有限。

    回到你原来使用 datetime 类型的问题,不确定你能否找到使用默认引擎的解决方案 (see here for supported datatype)

    【讨论】:

    • 谢谢 :) 我做了一个%timeit df_exade_light.eval('Date+Heure',engine='python'),结果是6.94 ms ± 309 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 所以确实不是更快
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多