扩展Python/Numpy性能的最佳方式
由于有多种为Python编写二进制模块的方法,如果我希望尽可能地提高某些代码的某些段的性能. P> 据我了解,可以使用Python/Numpy C-API编写扩展名,也可以包装一些已经编写的纯C/C ++/Fortran函数,可以从Python代码中调用. 自然,像Cython这样的工具是最简单的方法,但我认为手工编写代码可以提供更好的控制并提供更好的性能. 问题,可能是使用哪种方法.写C或C ++扩展名?包裹外部C/C ++功能或将回调用于Python功能? 我在阅读Langtangen的" Python脚本计算科学"中的第10章后写了这个问题,其中比较了Python和C. 之间的几种方法. 解决方案 我会说这取决于您的技能/经验和项目. 如果这很重要,并且您在C/C ++方面具有潜力,并且您已经编写了Python包装器,那么请编写自己的扩展名并将其连接. 如果您要在其他项目上与Numpy一起工作,那么请使用Numpy C-API,它的广泛且颇有文献记载
2 2024-04-10
编程技术问答社区
相当于在Numpy中使用#include <Numeric/arrayobject.h>。
我有一个旧的代码,它使用数字,我想与numpy交换. 也有一些C代码使用以下内容: #include 我想使用numpy做同样的事情,有没有办法这样做? 解决方案 因此,如果有人有兴趣 - 继续使用arrayObject.h,就像在旧数字系统中一样 执行以下操作: Replace with 但是新的arrayobject.h在数字的位置不同的位置,因此更新设置.py如下: 添加以下 import numpy as NU 然后在设置下(仍在setup.py中)添加以下 include_dirs = [NU.get_include()],
0 2024-04-09
编程技术问答社区
返回一个指向Python数组的2D Cython指针
我目前正在从Cython传递到C的以下指针: #convert the input Python 2D array to a memory view cdef double[:,:] a_cython= np.asarray(a,order="C") #define a pointer of a pointer with dimensions of a cdef double** point_to_a = malloc(N * sizeof(double*)) #initialize the pointer if not point_to_a: raise MemoryError #try: for i in range(N): point_to_a[i] = &a_cython[i, 0] #pass this double pointer to a C functio
0 2024-04-09
编程技术问答社区
Numpy是否会在通常的操作上重现所有C行为?
我正在设计Python中的算法,并且知道我想稍后将其翻译成C. 但是,python中的数学操作可能不会与C中的C中的C0>中的数学运算相同,例如,对于无符号整数而言,C0>的结果可能不会产生,而是使用普通的Python Integers操作.因此,我不应该在设计中使用Python整数. 我可以安全,可以轻松地使用numpy复制C行为吗?也就是说,如果我执行常规操作(+, - , *,/,%,从float到int或以相反的方式铸造),则使用类型np.uint32>或np.float64进行我可以以某种方式获得此保证)与uint32_t和float64_t的C程序相同的结果? 我只对C"官方行为"的一部分感兴趣,允许依赖C中的编译器或处理器的任何内容也可能与Numpy有所不同,就好像它是另一个编译器/处理器一样.我特别问,因为Numpy的NAN并不总是在c. 中 评论后编辑: 我更特别地寻找这组操作:(+, - , *,/,%,从float到int或以相反的方式铸
0 2024-04-09
编程技术问答社区
如何将熊猫数据框导出到具有二进制格式的文件中,然后读取C ++?
我有一个带有不同数据类型的熊猫数据框. 我想在C ++中使用它,出于性能原因,我想以二进制格式阅读它. 例如: In [4]: df = pd.DataFrame(np.reshape(range(9), (3, 3))) In [5]: df Out[5]: 0 1 2 0 0 1 2 1 3 4 5 2 6 7 8 In [6]: df['ticker'] = 'helloworld' In [7]: df['float'] = 1.12 In [8]: df Out[8]: 0 1 2 ticker float 0 0 1 2 helloworld 1.12 1 3 4 5 helloworld 1.12 2 6 7 8 helloworld 1.12 我尝试了numpy to_bytes,但似乎不起作用. with open('a.bin', 'wb')
0 2024-04-09
编程技术问答社区
用C函数扩展Numpy
我正在尝试加快我的numpy代码,并决定我想实现一个特定的功能,而我的代码大部分时间都花在c. 中 我实际上是C中的新秀,但是我设法编写了将矩阵中的每一行归一般到1的函数,我可以对其进行编译,并用一些数据(在C中)对其进行了测试,并且它可以做什么我想.那时我为自己感到非常自豪. 现在,我试图从Python调用我的光荣功能,在那里它应该接受一个2D-umpy数组. 我尝试的各种事情是 swig swig + numpy.i ctypes 我的功能具有原型 void normalize_logspace_matrix(size_t nrow, size_t ncol, double mat[nrow][ncol]); 因此,它需要指向变量长度数组并将其修改为适当的指针. 我尝试了以下纯Swig接口文件: %module c_utils %{ extern void normalize_logspace_matrix(size_t
0 2024-04-09
编程技术问答社区
指针类型与PyArray_SimpleNew不匹配
我正在使用C API使用Numpy为Python创建一个模块,并与PyArray_SimpleNew的输出遇到奇怪的不兼容性,我想理解.但首先是最小示例: # include # include void foo() { Py_Initialize(); import_array(); npy_intp dims[1] = {42}; PyObject * A = PyArray_SimpleNew(1,dims,NPY_DOUBLE); // Line A Py_Finalize(); } int main() { foo(); return 0; } 如果我用gcc source.c -lpython2.7 -I/usr/include/python2.7 --pedantic进行编译,我会得到(引用a): ISO C禁止对象指针转换为函数
0 2024-04-09
编程技术问答社区
pyarray_simplenewfromdata
因此,我正在尝试编写一个接受numpy数组对象,提取数据,进行一些操作并将另一个C数组作为numpy数组对象返回的C函数.一切都无缝地工作,我使用Python包装器,可以轻松在Python方面操纵.但是,我面临着记忆泄漏.我有一个我malloc-ed的输出指针,然后将其包装到Python数组对象中,然后再将其返回到调用Python函数, PyObject *arr; int nd = 2; npy_intp dims[] = {5, 10}; double *data = some_function_that_returns_a_double_star(x, y, z); arr = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, (void *)data); return arr; 但是,这会产生内存泄漏,因为数据永远不会释放,我进行了一些谷歌搜索以发现这是此类应用程序中的问题,而解决方案是非平凡的.我在此发现的最有用的资源是
0 2024-04-08
编程技术问答社区
计算平方欧几里得距离的可能的优化方法
我需要每天在一个Python项目中进行几亿欧几里得距离计算. 这是我开始的: def euclidean_dist_square(x, y): diff = np.array(x) - np.array(y) return np.dot(diff, diff) 这很快,我已经删除了SQRT计算,因为我只需要对项目进行排名(最近的邻居搜索).不过,它仍然是脚本的瓶颈.因此,我写了一个C扩展程序,该扩展可以计算距离.该计算始终使用128维向量完成. #include "euclidean.h" #include double euclidean(double x[128], double y[128]) { double Sum; for(int i=0;i
0 2024-04-08
编程技术问答社区
编译多个模块时,import_array()出现Numpy/CAPI错误
我正在尝试编译由由多个标头和源C ++文件组成的scipy.weave中的C ++模块.这些文件包含广泛使用Numpy/C-API接口的类和方法.但是我未能弄清楚如何成功地包括import_array().在过去的一周中,我一直在努力,我疯了.我希望您能为我提供帮助,因为weave 帮助不是很好. 实际上,我首先有一个称为pycapi_utils的模块,该模块包含一些与Python对象接口C对象的例程.它由标头文件pycapi_utils.h和一个源文件pycapi_utils.cpp,例如: //pycapi_utils.h #if ! defined _PYCAPI_UTILS_H #define _PYCAPI_UTILS_H 1 #include #include #include #include #include typedef std::tu
0 2024-04-08
编程技术问答社区
当我分配一个巨大的ndarray时,numpy empty在幕后做了什么?
我正在寻找内存中的空间numpy阵列消耗的东西,我注意到一种特殊的行为: 当我运行x = np.empty((1000000, 7, 64, 64), dtype=np.uint8) 时 我带有16GB内存的计算机没有崩溃.取而代 这个数阵列的重量应为26.70 GB,但似乎正在发生懒惰的事情.当我添加一个时,懒惰立即停止,我的程序悬挂了,它们会得到MemoryError. 我想知道Numpy如何在引擎盖下做到这一点. 我看了一个numpy.core.multiarray,并找到了numpy/core/src/multiarray/multiarraymodule.c,其中似乎是空的定义: static PyObject * array_empty(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds) { static char *kwlist[] = {"shape","dt
0 2024-04-08
编程技术问答社区
在Numpy数组上调用PyArg_ParseTuple时发生崩溃
我在C中写了一个简单的python扩展功能,该功能刚刚读取一个numpy数组,它崩溃了. static PyObject *test(PyObject *self, PyObject *args) { PyArrayObject *array = NULL; if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &array)) // Crash return NULL; return Py_BuildValue("d", 0); } 这是称为: 的方式 l = np.array([1,2,3,1,2,2,1,3]) print("%d" % extension.test(l)) 我的代码怎么了? 解决方案 我认为错误是在您未包括的代码中:您是否记得在模块INIT函数中调用import_array() import_array(): ...此子例程还必须包含对impo
4 2024-04-08
编程技术问答社区
NumPy C | API:将类型对象转换为类型数字
功能 PyObject* PyArray_TypeObjectFromType(int); 将numpy标量类型(npy_bool,npy_byte,...)转换为相应的类型对​​象. 您如何进行相反的转换,从numpy标量类型的类型对象到相应的类型编号? 编辑:以下代码基于Kwatford的答案.它接受两个类型的对象,例如int和numpy.int.int16,以及诸如" int",U" int"和" int16"的字符串. int numpyScalarTypeNumber(PyObject* obj) { PyArray_Descr* dtype; if(!PyArray_DescrConverter(obj, &dtype)) return NPY_NOTYPE; int typeNum = dtype->type_num; Py_DECREF(dtype); return typeNum; } 解决方案
0 2024-04-08
编程技术问答社区
如何为一个C语言分配的numpy数组注册一个析构器?
我想在C/C ++中分配一个numpy数组的数字,然后将它们作为numpy数组传递给Python.我可以用 pyarray_simplene_simplene_simplenewfromdata . 问题在于,当Numpy Array参考计数器达到零时,我还想注册一个应从Python调用的函数,这将在C侧调用某些Destructor语义...我需要的: float* arr; PyObject* np_arr; void (*destructor)(float* arr); // ... C-allocate array on arr, ... // ... // ... initialize destructor with some suitable value, and then: np_arr = /* ... create the array to wrap arr, and to use destructor on some m
0 2024-04-08
编程技术问答社区
将一组NumPy数组传入C函数进行输入和输出
让我们假设我们有一个C函数,该函数采用一组或多种输入数组,对其进行处理,然后将其输出写入一组输出数组中.签名看起来如下(count表示要处理的数组元素的数量): void compute (int count, float** input, float** output) 我想通过CTYPE从Python调用此功能,并使用它将转换应用于一组Numpy数组.对于单输入/单输出功能,定义为 void compute (int count, float* input, float* output) 以下工作: import ctypes import numpy from numpy.ctypeslib import ndpointer lib = ctypes.cdll.LoadLibrary('./block.so') fun = lib.compute fun.restype = None fun.argtypes = [ctypes.c_int,
0 2024-04-08
编程技术问答社区
为什么cffi比numpy快得多?
我一直在玩python编写CFFI模块,他们的速度使我想知道我是否正确使用了标准Python.这让我想完全切换到C!坦白说,有一些我永远无法在C中重新实现的很棒的Python图书馆,所以这比实际上更为假设. 此示例显示了与numpy阵列一起使用的Python中的总和函数,以及与C函数相比的速度.是否有更快的Pythonic方法计算Numpy数组的总和? def cast_matrix(matrix, ffi): ap = ffi.new("double* [%d]" % (matrix.shape[0])) ptr = ffi.cast("double *", matrix.ctypes.data) for i in range(matrix.shape[0]): ap[i] = ptr + i*matrix.shape[1]
0 2024-04-08
编程技术问答社区
多核机器上单精度阵列与双精度阵列的矩阵乘法的性能下降问题
更新 不幸的是,由于我的监督,我的MKL(11.1)与Numpy相关. MKL的较新版本(11.3.1)在C中提供了相同的性能,并从Python中调用时. 即使将编译的共享库明确链接到较新的MKL,并通过LD_*变量将其指向它们,然后在Python进行import numpy的情况下,以某种方式使Python Call Call Call Call old Mkl库将 掩盖了事物.仅通过在Python Lib文件夹中替换所有libmkl _*. 背景/库信息. 矩阵乘法是通过sgemm(单精度)和DGEMM(双重精确)Intel的MKL库呼叫完成的.可以通过例如Oprof. 使用此处2x18 Core CPU E5-2699 V3,因此总共36个物理核心. kmp_affinity =散布.在Linux上运行. tl; dr 1)为什么numpy.dot,即使它调用了相同的MKL库功能,与C编译的代码相比,最多要慢两次? 2)为什么通过num
0 2024-04-07
编程技术问答社区
使用numpy/ctypes暴露一个C分配的内存缓冲区的更安全的方法?
我正在为C库编写Python绑定,该库使用共享内存缓冲器存储其内部状态.这些缓冲区的分配和释放是在图书馆本身外部在Python之外完成的,但是我可以通过调用Python内部调用包装构造函数/Destructor函数来间接控制这种情况.我想将一些缓冲区暴露于Python,以便我可以从它们中阅读,在某些情况下,将值推向它们.性能和记忆使用是重要的问题,因此我想避免在可能的情况下复制数据. 我当前的方法是创建一个Numpy数组,该数组可直接在CTypes指针上: import numpy as np import ctypes as C libc = C.CDLL('libc.so.6') class MyWrapper(object): def __init__(self, n=10): # buffer allocated by external library addr = libc.malloc(C.sizeof(C.c_int
0 2024-04-07
编程技术问答社区
Cython中的复数
在Cython中使用复数的正确方法是什么? 我想使用numpy.npe np.complex128编写纯C循环.在Cython中,相关的C类型定义 Cython/Includes/numpy/__init__.pxd AS ctypedef double complex complex128_t 所以看来这只是一个简单的C双复合物. 但是,很容易获得奇怪的行为.特别是,使用这些定义 cimport numpy as np import numpy as np np.import_array() cdef extern from "complex.h": pass cdef: np.complex128_t varc128 = 1j np.float64_t varf64 = 1. double complex vardc = 1j double vard = 1. 线 varc128 = varc128 *
0 2024-04-07
编程技术问答社区