我在我的python程序中使用cython进行相关计算.我有两个音频数据集,我需要知道它们之间的时差.基于开始时间切割第二组,然后滑过第一组.有两个for循环:一个滑动集合,内循环计算该点的相关性.这种方法效果很好,而且足够准确.
问题是使用纯python这需要一分多钟.使用我的cython代码,大约需要17秒.这仍然太多了.您是否有任何提示如何加速此代码:
import numpy as np
cimport numpy as np
cimport cython
FTYPE = np.float
ctypedef np.float_t FTYPE_t
@cython.boundscheck(False)
def delay(np.ndarray[FTYPE_t, ndim=1] f, np.ndarray[FTYPE_t, ndim=1] g):
cdef int size1 = f.shape[0]
cdef int size2 = g.shape[0]
cdef int max_correlation = 0
cdef int delay = 0
cdef int current_correlation, i, j
# Move second data set frame by frame
for i in range(0, size1 - size2):
current_correlation = 0
# Calculate correlation at that point
for j in range(size2):
current_correlation …Run Code Online (Sandbox Code Playgroud) 考虑一个简单的函数
def increment(self):
self.count += 1
Run Code Online (Sandbox Code Playgroud)
它通过Cython运行并编译成扩展模块.假设现在我想把这个函数作为一个类的方法.例如:
class Counter:
def __init__(self):
self.count = 0
from compiled_extension import increment
Counter.increment = increment
Run Code Online (Sandbox Code Playgroud)
现在这不起作用,因为C级别的调用约定将被打破.例如:
>>> c = Counter()
>>> c.increment()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: increment() takes exactly one argument (0 given)
Run Code Online (Sandbox Code Playgroud)
但是在Python 2中,我们可以通过执行以下操作将函数转换为未绑定的方法:
Counter.increment = types.MethodType(increment, None, Counter)
Run Code Online (Sandbox Code Playgroud)
我怎样才能在Python 3中完成同样的事情?
一种简单的方法是使用纤薄的包装:
from functools import wraps
def method_wraper(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wraps(f)(wrapper)
Counter.increment = method_wrapper(increment)
Run Code Online (Sandbox Code Playgroud)
有更有效的方法吗?
我正在对http://docs.cython.org/src/tutorial/numpy.html上的素数生成器的变体进行一些性能测试.以下性能测量值为kmax = 1000
纯Python实现,在CPython中运行:0.15s
纯Python实现,在Cython中运行:0.07s
def primes(kmax):
p = []
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p.append(n)
k = k + 1
n = n + 1
return p
Run Code Online (Sandbox Code Playgroud)
纯Python + Numpy实现,在CPython中运行:1.25s
import numpy
def primes(kmax):
p = numpy.empty(kmax, dtype=int)
k = 0
n = 2
while k < kmax:
i = …Run Code Online (Sandbox Code Playgroud) 我正在寻找解决方案来加速我编写的函数来循环遍历pandas数据帧并比较当前行和前一行之间的列值.
例如,这是我的问题的简化版本:
User Time Col1 newcol1 newcol2 newcol3 newcol4
0 1 6 [cat, dog, goat] 0 0 0 0
1 1 6 [cat, sheep] 0 0 0 0
2 1 12 [sheep, goat] 0 0 0 0
3 2 3 [cat, lion] 0 0 0 0
4 2 5 [fish, goat, lemur] 0 0 0 0
5 3 9 [cat, dog] 0 0 0 0
6 4 4 [dog, goat] 0 0 0 0
7 4 11 [cat] 0 0 …Run Code Online (Sandbox Code Playgroud) 我想Cython通过使用将一些额外的选项传递给编译器extra_compile_args.
我的setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'Test app',
ext_modules = cythonize("test.pyx", language="c++", extra_compile_args=["-O3"]),
)
Run Code Online (Sandbox Code Playgroud)
但是,当我跑步时python setup.py build_ext --inplace,我收到以下警告:
UserWarning: got unknown compilation option, please remove: extra_compile_args
Run Code Online (Sandbox Code Playgroud)
问题:如何extra_compile_args正确使用?
我用Cython 0.23.4下了Ubuntu 14.04.3.
在探索 Cython 编译步骤时,我发现我需要在 setup.py 中明确链接 C 库,如 math。但是,numpy 不需要这样的步骤。为什么这样?numpy 是通过通常的 python 导入机制导入的吗?如果是这样,我们不需要在 Cython 中显式链接任何扩展模块?
我试图翻阅官方文档,但不幸的是,没有解释何时需要显式链接以及何时自动处理。
我正在寻找一种有效的数据结构来表示Python/Cython中非常大的整数矩阵,重点关注元素操作.
我目前正在构建一个模型,该模型需要在大型高度稀疏矩阵上进行大量元素操作(在2MMx500k矩阵上读取/写入大约500亿次).以前我在较小的数据上运行实验,并使用Python与Cython和Numpy数组,并且理想情况下将继续使用现有基础结构的某些部分.
到目前为止我已查看/实施了许多选项.它们可能没有完全优化,但所有实现都应该足够好,以便对每种方法的潜力给出切合实际的想法.我已经通过创建一个2MMx500k矩阵进行测试,添加了25MM元素,然后再次删除它们.这反映了我需要的那种操作.
29 minutes: Cython lists to fill scipy.sparse.coo -> sparse.dok
10 minutes: Cython lists to fill scipy.sparse.coo -> sparse.lil
3 minutes: Dict, s.t. A["%d_%d" % (i,j)] contains M[i][j]
3 minutes: Dict, s.t. A[(i,j)] contains M[i][j]
<1 minute: Dict, s.t. A[i*N,j] contains M[i][j]
<1 minute: <std::map> using Cython
Run Code Online (Sandbox Code Playgroud)
到目前为止,黑客攻击一个词典表现最好,但仍然相当慢.这也感觉太糟糕了,所以我假设必须有一个更有效的方法,特别是考虑到dict解决方案并没有真正使用任何潜在的Cython可以提供.是否有更多的Cythonic解决方案?不幸的是,谷歌并没有太大的帮助(或者我没有正确的搜索关键词).
任何有关如何做到这一点的建议将不胜感激!
编辑1
两个字典解决方案之间的区别在于A ["%d_%d"%(i,j)]变体访问速度更快,而A [(i,j)]变体的设置速度更快.
Setup Execution
Dict, s.t. A["%d_%d" % (i,j)] contains M[i][j] 180s 30s
Dict, s.t. A[(i,j)] contains M[i][j] 66s 104s
Dict, s.t. Dict, s.t. A[i*N,j] contains M[i][j] …Run Code Online (Sandbox Code Playgroud) 我想在Cython中做到这一点:
cdef int shiftIndexes[] = [1,-1, 0, 2,-1, -1, 4, 0, -1, 8, 1, -1, 16, 1, 0, 32, 1, 1, 64, 0, 1, 128, -1, 1]
Run Code Online (Sandbox Code Playgroud)
我已经在固定的bug报告和旧的电子邮件列表中看到一些参考,Cython中存在静态数组功能,但是我找不到anty示例,这个特定的例子给我一个语法错误: Syntax error in C variable declaration
是否可以使用Cython制作静态C数组?
我想知道如何使用Cython将普通的python列表转换为C列表,处理它并返回一个python列表.喜欢:
Python脚本:
import mymodule
a = [1,2,3,4,5,6]
len = len(a)
print(mymodule.process(a,len))
Run Code Online (Sandbox Code Playgroud)
Cython脚本(mymodule.pyd):
cpdef process(a, int len):
cdef float y
for i in range(len):
y = a[i]
a[i] = y * 2
return a
Run Code Online (Sandbox Code Playgroud)
我读到了关于MemoryView和许多其他的东西,但我并不是真的知道发生了什么,很多例子使用Numpy(我不想用它来避免我的脚本用户下载一个大包...反正我觉得它不是'使用我的软件).我需要一个非常简单的例子来了解究竟发生了什么.
我尝试在Windows 7下使用Cython和Python3(Anaconda3).通过编辑文件cygwinccompiler.py解决了distutils中的错误(参见在Windows 7下使用python 3.3(Anaconda)构建最小的cython文件),可以构建模块没有任何问题:
C:\path\testcython> python setup.py build
running build
running build_ext
cythoning testcython.pyx to testcython.c
building 'testcython' extension
C:\Prog\Anaconda3\Scripts\gcc.bat -mdll -O -Wall -IC:\Prog\Anaconda3\include -IC
:\Prog\Anaconda3\include -c testcython.c -o build\temp.win-amd64-3.4\Release\tes
tcython.o
writing build\temp.win-amd64-3.4\Release\testcython.def
C:\Prog\Anaconda3\Scripts\gcc.bat -shared -s build\temp.win-amd64-3.4\Release\te
stcython.o build\temp.win-amd64-3.4\Release\testcython.def -LC:\Prog\Anaconda3\l
ibs -LC:\Prog\Anaconda3\PCbuild\amd64 -lpython34 -lmsvcr100 -o build\lib.win-amd
64-3.4\testcython.pyd
Run Code Online (Sandbox Code Playgroud)
但是,只要.pyx文件中有import或print语句,生成的.pyd文件就会使Python崩溃.例如,如果testcython.pyx包含
def say_hello_to(name):
print('Hello '+name)
Run Code Online (Sandbox Code Playgroud)
它给
In [1]: import testcython # no crash here
In [2]: testcython.say_hello_to('Tom')
Hello Tom
Run Code Online (Sandbox Code Playgroud)
这里弹出"Python.exe已停止工作"窗口,它已经完成.
在那种情况下(没有错误日志崩溃,我猜想分段错误),我该怎么做才能理解这个问题?
有谁知道在Windows下使用Cython,Python 3(Anaconda3)会发生什么?
PS:Python 2.7(Anaconda)没问题.
编辑:模块faulthandler生成的跟踪
如果testcython.pyx只包含:
print('Test print... Will it …Run Code Online (Sandbox Code Playgroud)