Python 带字符串和datetime64的Numba布尔索引

Python 带字符串和datetime64的Numba布尔索引,python,numpy,indexing,boolean,numba,Python,Numpy,Indexing,Boolean,Numba,我试图将一个基于日期和名称生成布尔索引的函数转换为与Numba一起使用,但我有一个错误 我的项目从一个Dataframe TS_Flujos开始,其结构如下 Fund name, Date, Var Commitment Cash flow Fund 1 Date 1 100 -20 Fund 1 Date 2 10 -2 Fund 1 Date 3 0 +10 Fund 2 Date 3 100

我试图将一个基于日期和名称生成布尔索引的函数转换为与Numba一起使用,但我有一个错误

我的项目从一个Dataframe TS_Flujos开始,其结构如下

Fund name, Date, Var Commitment Cash flow
Fund 1    Date 1  100           -20
Fund 1    Date 2  10            -2
Fund 1    Date 3  0             +10
Fund 2    Date 3  100            0
Fund 2    Date 4  0             -10
Fund 3    Date 2  100           -20
Fund 3    Date 3  20             30
每一行都是特定基金的现金流。对于每一行,我需要计算到目前为止的累计承诺,并减去到目前为止的融资金额,即“未融资”。为此,我在数据框TS_Flujos上迭代,识别基金和日期,使用布尔索引识别数据框中的其他“相关行”,即相同基金中的一行,并使用以下函数识别当前基金之前的日期:

def date_and_fund(date, fund, c_dates, c_funds):
    i1 = (c_dates <= date)
    i2 = (c_funds == fund)
    result = i1 & i2
    return result
这是一种简化,但我还按类型分离现金流,并计算每行的许多其他指标。现在我有44000行,但这个数字在将来会增加很多,这个循环已经需要1分钟到2分钟,这取决于计算机。我担心的速度,当我x10的现金流数据库,这是一个小部分的总项目。我试图理解如何使用您以前的答案来优化它,但我找不到一种方法来矢量化或使用列表理解

因为在计算中没有依赖关系,所以我尝试用Numba来并行代码

@njit(parallel=True)
def cashflow(array_cashflows):

    for index in prange(len(array_cashflows)):

        f = n_dates[index]
        p = n_funds[index]
        date_funds = date_and_fund(f, p, n_dates, n_funds)

        TS_Flujos['Cumulated commitment'].values[index] = n_varCommitment[date_fund].sum()
    return

flujos(n_dates)
但我得到了以下错误:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/ferna/OneDrive/Python/Datalts/Dataltsweb.py", line 347, in <module>
    flujos(n_fecha)
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\dispatcher.py", line 415, in _compile_for_args
    error_rewrite(e, 'typing')
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\dispatcher.py", line 358, in error_rewrite
    reraise(type(e), e, None)
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\utils.py", line 80, in reraise
    raise value.with_traceback(tb)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'date_and_pos': cannot determine Numba type of <class 'function'>
File "Dataltsweb.py", line 324:
def flujos(array_flujos):
    <source elided>
        p = n_idpos[index]
        fecha_pos = date_and_pos(f, p, n_fecha, n_idpos)
        ^
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\\u pydev_bundle\pydev_umd.py”,第197行,在runfile中
pydev_imports.execfile(文件名、全局变量、本地变量)#执行脚本
文件“C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\\u pydev\u imps\\u pydev\u execfile.py”,在execfile中的第18行
exec(编译(内容+“\n”,文件,'exec'),全局,loc)
文件“C:/Users/ferna/OneDrive/Python/Datalts/Dataltsweb.py”,第347行,在
flujos(n_fecha)
文件“C:\Users\ferna\venv\lib\site packages\numba\core\dispatcher.py”,第415行,位于编译参数中
重写错误(例如,“键入”)
文件“C:\Users\ferna\venv\lib\site packages\numba\core\dispatcher.py”,第358行,错误\u重写
重放(类型(e),e,无)
文件“C:\Users\ferna\venv\lib\site packages\numba\core\utils.py”,第80行,重新登录
通过_回溯(tb)提升值
numba.core.errors.TypingError:在nopython模式管道中失败(步骤:nopython前端)
非类型化全局名称“日期和位置”:无法确定
文件“Dataltsweb.py”,第324行:
def flujos(阵列\u flujos):
p=n_idpos[指数]
fecha_pos=日期和位置(f、p、n_fecha、n_idpos)
^

考虑到您构建代码的方式,使用Numba不会获得任何性能。您正在对一个已经矢量化的函数使用decorator,它将执行得很快。有意义的是尝试加速主循环,而不仅仅是
CapComp\u MO

关于错误,似乎与类型有关。尝试添加显式类型,看看它是否解决了问题,是Numba的datetime对象数据类型

我还建议您避免使用
.iterrows()
有关性能问题的说明,请参阅。 作为旁注,
t1[:]
:这需要一个完整的切片,与
t1
相同


此外,如果您添加一个最小的示例(代码和数据帧),它可能有助于改进您当前的方法。看起来您只是在每个迭代中建立索引,因此如果使用numpy,可能根本不需要循环。

鉴于您构建代码的方式,使用Numba不会获得任何性能。您正在对一个已经矢量化的函数使用decorator,它将执行得很快。有意义的是尝试加速主循环,而不仅仅是
CapComp\u MO

关于错误,似乎与类型有关。尝试添加显式类型,看看它是否解决了问题,是Numba的datetime对象数据类型

我还建议您避免使用
.iterrows()
有关性能问题的说明,请参阅。 作为旁注,
t1[:]
:这需要一个完整的切片,与
t1
相同


此外,如果您添加一个最小的示例(代码和数据帧),它可能有助于改进您当前的方法。看起来您只是在每次迭代中建立索引,因此如果您使用numpy,可能根本不需要循环。

感谢您的建议/评论,我将尝试实现主循环的优化,并发送更相关的代码版本!希望答案对@FernandoP有帮助?别忘了你可以投票并接受答案。看,谢谢!亲爱的Yatu,我一直在编写代码,但我就是找不到加速主循环的方法。如果你能帮我的话,我在上一篇文章中添加了一些细节。你有反馈吗?谢谢你的建议/评论,我将尝试实现主循环的优化,并发送一个更相关的代码版本!希望答案对@FernandoP有帮助?别忘了你可以投票并接受答案。看,谢谢!亲爱的Yatu,我一直在编写代码,但我就是找不到加速主循环的方法。如果你能帮我的话,我在上一篇文章中添加了一些细节。你有反馈吗?
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm 2020.1.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/ferna/OneDrive/Python/Datalts/Dataltsweb.py", line 347, in <module>
    flujos(n_fecha)
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\dispatcher.py", line 415, in _compile_for_args
    error_rewrite(e, 'typing')
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\dispatcher.py", line 358, in error_rewrite
    reraise(type(e), e, None)
  File "C:\Users\ferna\venv\lib\site-packages\numba\core\utils.py", line 80, in reraise
    raise value.with_traceback(tb)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Untyped global name 'date_and_pos': cannot determine Numba type of <class 'function'>
File "Dataltsweb.py", line 324:
def flujos(array_flujos):
    <source elided>
        p = n_idpos[index]
        fecha_pos = date_and_pos(f, p, n_fecha, n_idpos)
        ^