我正在尝试使用Cython包装使用某些OpenCV类型作为参数的C ++类,然后打算从Python使用此包装的类。C ++类的简化版本如下所示:
“ transform.h”
#include "opencv2/core/core.hpp"
namespace geom
{
class Transform
{
public:
Transform(cv::Vec3d &euler, cv::Vec3d &t);
void set_euler(cv::Vec3d &euler);
cv::Vec3d get_euler();
}
}
Run Code Online (Sandbox Code Playgroud)
Vec3d在OpenCV中定义为:
template<typename _Tp, int n> class Vec : public Matx<_Tp, n, 1> {...};
typedef Vec<double, 3> Vec3d;
Run Code Online (Sandbox Code Playgroud)
Matx定义为:
template<typename _Tp, int m, int n> class Matx {...};
Run Code Online (Sandbox Code Playgroud)
我对cython包装器的第一次尝试是这样的:
“ geom_gateway.pyx”
cdef extern from "opencv2/core/core.hpp" namespace "cv":
cdef cppclass Matx[_Tp, int m, int n]:
Matx()
Matx(_Tp v0, _Tp v1, _Tp v2)
cdef extern from "opencv2/core/core.hpp" namespace …Run Code Online (Sandbox Code Playgroud) 为了优化我的代码速度,这对我的 MCMC 的速度非常重要,我想用 cython 替换我的 python 代码的一些瓶颈。由于我正在使用一个巨大的二维数组,我需要根据二维数组的一列对数据进行分箱,然后根据第一列中的分箱在所有其他列中找到每个分箱中的平均值,我曾经使用过这个蟒蛇代码:
import numpy as np
d = np.random.random((10**5, 3))
#binning data again based on first column
bins = np.linspace(ndata[0,0], ndata[-1,0], 10)
#compute the mean in each bin for different input parameters
digitized = np.digitize(ndata[:,0], bins)
r= np.array([ndata[digitized == i,0].mean() for i in range(1, len(bins))])
p= np.array([ndata[digitized == i,1].mean() for i in range(1, len(bins))])
q= np.array([ndata[digitized == i,2].mean() for i in range(1, len(bins))])
Run Code Online (Sandbox Code Playgroud)
我怎样才能cython通过使用另一个代码而不是代码将代码加速至少两个数量级numpy.digitize?
我试图在 Windows 上编译 Cython 文件 (.pyx),这是我刚从 .py 保存的文件。这是我的项目目录路径。
c:\..\Project\App\Analyzer\
_init_.py
Few_other_files.py
consolidated_loop_C.pyx
cl_setup.py
Run Code Online (Sandbox Code Playgroud)
这是我的 cl_setup.py
from Cython.Build import cythonize
try:
from setuptools import setup
from setuptools import Extension
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
setup(
name = "Consolidated Loop",
ext_modules = cythonize("consolidated_loop_C.pyx")
)
Run Code Online (Sandbox Code Playgroud)
我正在使用以下语句在同一文件夹中进行编译。
python cl_setup.py build_ext --inplace
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误。我的猜测是我缺少 cythonize() 的某些参数,试图在没有任何运气的情况下进行研究。
我试图将C代码公开给cython,并尝试使用另一个cython模块中的c文件中定义的函数时遇到“未定义符号”错误。
我的h文件中定义的函数以及使用手动包装的函数都可以正常工作。
基本上与这个问题相同,但是解决方案(针对库的链接)对我来说并不令人满意。
我认为我在setup.py脚本中缺少什么?
foo.h
int source_func(void);
inline int header_func(void){
return 1;
}
Run Code Online (Sandbox Code Playgroud)
foo.c
#include "foo.h"
int source_func(void){
return 2;
}
Run Code Online (Sandbox Code Playgroud)
cdef extern from "foo.h":
int source_func()
int header_func()
cdef source_func_wrapper()
Run Code Online (Sandbox Code Playgroud)
foo_wrapper.pyx
cdef source_func_wrapper():
return source_func()
Run Code Online (Sandbox Code Playgroud)
cimport foo_wrapper
def do_it():
print "header func"
print foo_wrapper.header_func() # ok
print "source func wrapped"
print foo_wrapper.source_func_wrapper() # ok
print "source func"
print foo_wrapper.source_func() # undefined symbol: source_func
Run Code Online (Sandbox Code Playgroud)
foo_wrapper和test_lib
cdef extern from …Run Code Online (Sandbox Code Playgroud) 我试图找到使用 Cython 对 numpy 数组进行水平求和的最快方法。首先,假设我有一个 10 x 100,000 随机浮点数的 2D 数组。我可以创建一个object数组,每列作为数组中的一个值,如下所示:
n = 10 ** 5
a = np.random.rand(10, n)
a_obj = np.empty(n, dtype='O')
for i in range(n):
a_obj[i] = a[:, i]
Run Code Online (Sandbox Code Playgroud)
我想做的就是找到每一行的总和。它们都可以这样简单地计算:
%timeit a.sum(1)
414 µs ± 24.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit a_obj.sum()
113 ms ± 7.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
对象数组慢 250 倍。
在尝试总结之前,我想对每个元素的访问时间进行计时。Cython 在直接遍历每个项目时无法加速访问对象数组的每个成员:
def access_obj(ndarray[object] …Run Code Online (Sandbox Code Playgroud) 我正在编写Python代码来加速二进制图像中标记对象的区域属性函数.以下代码将根据对象的索引计算二进制图像中标记对象的边界像素数.main()函数将遍历二进制图像"mask"中的所有标记对象,并计算每个对象的边框像素数.
我想知道在这个Cython代码中传递或返回变量的最佳方法是什么.变量可以是NumPy数组,也可以是类型化的Memoryviews.我已经在绕过搞砸/在不同的格式返回变量,但不能推导出最佳/最有效的方法是什么.我是新来用Cython所以Memoryviews仍然相当抽象的我,是否有这两种方法之间的不同仍是一个谜.我正在使用的图像包含100,000多个标记对象,因此这些操作需要相当高效.
总结一下:
什么时候/我应该将我的变量作为类型化的Memoryviews而不是NumPy数组传递/返回以进行非常重复的计算?有没有最好的方式或者它们是完全一样的?
%%cython --annotate
import numpy as np
import cython
cimport numpy as np
DTYPE = np.intp
ctypedef np.intp_t DTYPE_t
@cython.boundscheck(False)
@cython.wraparound(False)
def erode(DTYPE_t [:,:] img):
# Image dimensions
cdef int height, width, local_min
height = img.shape[0]
width = img.shape[1]
# Padded Array
padded_np = np.zeros((height+2, width+2), dtype = DTYPE)
cdef DTYPE_t[:,:] padded = padded_np
padded[1:height+1,1:width+1] = img
# Eroded image
eroded_np = np.zeros((height,width),dtype=DTYPE)
cdef DTYPE_t[:,:] eroded = eroded_np
cdef DTYPE_t i,j
for i in range(height):
for j …Run Code Online (Sandbox Code Playgroud) 如何在Cython 中执行与以下 C++ 代码等效的代码?
typedef vector<double> dvec;
dvec *arr = new dvec[n]; // n is an unsigned int (unknown at compile time)
// do something with arr; for example...
arr[0].push_back(10);
cout << arr[0][0] << endl;
Run Code Online (Sandbox Code Playgroud)
我试图为 n 个向量分配内存,但是我不知道如何在 Cython 中进行新的放置。任何帮助将不胜感激。
我无法找到太多关于此的信息,但是当尝试使用 cython 编译我的一个 python 脚本时,它给了我这个错误:
Error compiling Cython file:
------------------------------------------------------------
...
import traceback #line:24
import bcrypt #line:25
Y =str (os .path .dirname (os .path .abspath (__file__ )))#line:28
IH =open #line:29
IA =str #line:30
IK =print #line:31
^
------------------------------------------------------------
headlessobfu.pyx:29:4: Expected an identifier or literal
Traceback (most recent call last):
File "setup.py", line 5, in <module>
ext_modules = cythonize("headlessobfu.pyx")
File "C:\Users\justi\AppData\Local\Programs\Python\Python36-32\lib\site-packages\Cython\Build\Dependencies.py", line 1026, in cythonize
cythonize_one(*args)
File "C:\Users\justi\AppData\Local\Programs\Python\Python36-32\lib\site-packages\Cython\Build\Dependencies.py", line 1146, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: headlessobfu.pyx
Run Code Online (Sandbox Code Playgroud)
我一直无法找到此错误的确切原因。我能够得到简单的脚本来编译就好了。蟒蛇自己运行得很好。我的python格式有问题吗?
这是我正在运行的命令行参数:
py setup.py …Run Code Online (Sandbox Code Playgroud) 我正进入(状态:
KilledWorker: ("('from_pandas-1445321946b8a22fc0ada720fb002544', 4)", 'tcp://127.0.0.1:45940')
我已经阅读了关于后一个错误消息的解释,但这与堆栈跟踪顶部的错误消息一起出现令人困惑:
distributed.utils - 错误 - Worker 已经存在 tcp://127.0.0.1:35780
实际错误通过管道传输到Jupyter notebook为我的笔记本运行命令的终端:
ModuleNotFoundError:没有名为“_cython_magic_faba6120a194ab58ae9efd1da474433f”的模块
所以我将自己研究如何解决这个问题,现在我在我的案例中发现了详细的错误。关于这种特殊配置的精确提示会很好,但我想将所有 cython 代码提取到笔记本外部的 python 代码中更明智,而不是敲击了解 cython 魔术命令?
我有一些我想使用 Cython 并行执行的独立计算。
现在我正在使用这种方法:
import numpy as np
cimport numpy as cnp
from cython.parallel import prange
[...]
cdef cnp.ndarray[cnp.float64_t, ndim=2] temporary_variable = \
np.zeros((INPUT_SIZE, RESULT_SIZE), np.float64)
cdef cnp.ndarray[cnp.float64_t, ndim=2] result = \
np.zeros((INPUT_SIZE, RESULT_SIZE), np.float64)
for i in prange(INPUT_SIZE, nogil=True):
for j in range(RESULT_SIZE):
[...]
temporary_variable[i, j] = some_very_heavy_mathematics(my_input_array)
result[i, j] = some_more_maths(temporary_variable[i, j])
Run Code Online (Sandbox Code Playgroud)
这种方法有效,但我的问题来自事实上我需要几个temporary_variables。这会在增长时导致大量内存使用INPUT_SIZE。但我相信真正需要的是每个线程中的临时变量。
我是否面临 Cython 的恶作剧的限制,我是否需要学习正确的 C 语言,或者我是否在做/理解一些非常错误的事情?
编辑:我一直在寻找的功能都openmp.omp_get_max_threads()和openmp.omp_get_thread_num()创建合理大小的临时数组。我必须cimport openmp先。
cython ×10
python ×6
numpy ×4
c++ ×2
arrays ×1
compilation ×1
dask ×1
gil ×1
memoryview ×1
opencv ×1