当参数和 returns 是矩阵而不是标量时使用 cython
Using cython when arguments and returns are matrices, not scalars
我是 cython 的新手,我想更快地对 pandas DataFrames 进行计算。这是此类计算的一个典型的简化示例。在此示例中,参数是向量,return 是标量,但在其他情况下,参数和 return 都可以是 DataFrame/arrays。我有很多这样的功能,它们有时是嵌套的。
import pandas as pd
import numpy as np
def f(x,y,z):
return np.dot(x,np.exp(x*y/(1-np.power(z,3))))
df = pd.DataFrame({'a': np.random.randn(1000), 'b':
np.random.randn(1000),'c': np.random.randint(100, 1000, (1000))})
print(f(df.a,df.b,df.c))
在我看到的教程和文档中,cython 用于优化标量的计算,而不是matrices/arrays(例如http://pandas.pydata.org/pandas-docs/stable/enhancingperf.html)。因此,该过程通常涉及向标量添加类型(int、float、double 等)。在函数使用 DataFrames 或数组作为参数和 returns 而不是标量的情况下,使用 cython 的正确过程是什么?
我尝试了以下方法,但没有看到任何明显的改进(尽管没有抛出错误):
@cython.locals(x=cython.float,y=cython.float,z=cython.float)
@cython.returns(cython.float)
def f(x,y,z):
return np.dot(x,np.exp(x*y/(1-np.power(z,3))))
提前致谢
查看您的函数内部:您只调用了 numpy 函数,也就是说,您为 Cython 转换为 C 代码留了一小部分(如果有的话)余量。
你 可能 如果你输入你的变量如数组的 double[:] 来提高速度(老实说,我不知道在哪里,但编译器的优化通常更聪明比自己)。但是你的函数仍然主要是 numpy 函数的包装器:Cython 不会改进它们的内部工作。
不过,您可以尝试实现自己的外部乘积函数,并在那里获得一些速度(我不知道 numpy 的效率如何,但您可能会比它稍胜一筹)。另外,使用 C 的 exp
和 math.h
中的 pow
可能会进一步改进。
Cython 没有 'type-definign' 个变量,但您必须确保在调用 cython 的编译器时,它能够将尽可能多的代码转换为 C 语言。 (顺便说一句,你正在编译你的代码,对吧?只有当你编译你的源代码并导入生成的模块时才会看到速度提升;运行 它在 pure-python 模式下只是 Python).
我是 cython 的新手,我想更快地对 pandas DataFrames 进行计算。这是此类计算的一个典型的简化示例。在此示例中,参数是向量,return 是标量,但在其他情况下,参数和 return 都可以是 DataFrame/arrays。我有很多这样的功能,它们有时是嵌套的。
import pandas as pd
import numpy as np
def f(x,y,z):
return np.dot(x,np.exp(x*y/(1-np.power(z,3))))
df = pd.DataFrame({'a': np.random.randn(1000), 'b':
np.random.randn(1000),'c': np.random.randint(100, 1000, (1000))})
print(f(df.a,df.b,df.c))
在我看到的教程和文档中,cython 用于优化标量的计算,而不是matrices/arrays(例如http://pandas.pydata.org/pandas-docs/stable/enhancingperf.html)。因此,该过程通常涉及向标量添加类型(int、float、double 等)。在函数使用 DataFrames 或数组作为参数和 returns 而不是标量的情况下,使用 cython 的正确过程是什么?
我尝试了以下方法,但没有看到任何明显的改进(尽管没有抛出错误):
@cython.locals(x=cython.float,y=cython.float,z=cython.float)
@cython.returns(cython.float)
def f(x,y,z):
return np.dot(x,np.exp(x*y/(1-np.power(z,3))))
提前致谢
查看您的函数内部:您只调用了 numpy 函数,也就是说,您为 Cython 转换为 C 代码留了一小部分(如果有的话)余量。
你 可能 如果你输入你的变量如数组的 double[:] 来提高速度(老实说,我不知道在哪里,但编译器的优化通常更聪明比自己)。但是你的函数仍然主要是 numpy 函数的包装器:Cython 不会改进它们的内部工作。
不过,您可以尝试实现自己的外部乘积函数,并在那里获得一些速度(我不知道 numpy 的效率如何,但您可能会比它稍胜一筹)。另外,使用 C 的 exp
和 math.h
中的 pow
可能会进一步改进。
Cython 没有 'type-definign' 个变量,但您必须确保在调用 cython 的编译器时,它能够将尽可能多的代码转换为 C 语言。 (顺便说一句,你正在编译你的代码,对吧?只有当你编译你的源代码并导入生成的模块时才会看到速度提升;运行 它在 pure-python 模式下只是 Python).