我有一个大型二进制数据文件,我想将其加载到 C 数组中以便快速访问。数据文件仅包含 4 字节整数序列。
我通过 pkgutil.get_data 函数获取数据,该函数返回一个二进制字符串。以下代码有效:
import pkgutil
import struct
cdef int data[32487834]
def load_data():
global data
py_data = pkgutil.get_data('my_module', 'my_data')
for i in range(32487834):
data[i] = <int>struct.unpack('i', py_data[4*i:4*(i+1)])[0]
return 0
load_data()
Run Code Online (Sandbox Code Playgroud)
问题是这段代码非常慢。读取整个数据文件可能需要 7 或 8 秒。将文件直接读入 C 中的数组只需 1-2 秒,但我想使用 pkgutil.get_data 以便我的模块无论安装在何处都可以可靠地找到数据。
所以,我的问题是:最好的方法是什么?有没有办法直接将数据转换为整数数组,而不需要对 struct.unpack 进行所有调用?而且,作为第二个问题,有没有一种方法可以简单地获取指向数据的指针,以避免不必要地复制 120MB 的数据?
或者,有没有办法让 pkgutil 返回数据的文件路径而不是数据本身(在这种情况下,我可以使用 C 文件 IO 来快速读取文件。
编辑:
仅供记录,这是最终使用的代码(基于 Veedrac 的答案):
import pkgutil
from cpython cimport array
import array
cdef int[:] data
cdef void load_data():
global data
py_data = pkgutil.get_data('my_module', …Run Code Online (Sandbox Code Playgroud) 我试图在Cython中为Python编写一个运行长度编码算术库.下面你会看到声明和算法热循环的重要部分是如何看的.它有两个地方有很多和中等的Python交互,第73-74行和第77行.为重度Python交互部分生成的C代码最后显示在一张图片中.我只会询问如何在这里解决73-74,因为我认为77的修复程序是相似的.
正如您所看到的,在生成的C代码中有1)很多类型转换,2)它使用richcompare和3)getitemint.我不明白为什么:1)类型应该是相同的,2)比较应该可以在C级别,因为他们只是比较相同类型的数字和3)getitem应该是多余的,因为你只是查找一个C数组中的索引.
如何解决这个问题以优化我的代码?numpy数组声明创建Python对象的问题是否需要以某种方式指向它们?
在这里,您可以看到为我的热循环中的两个黑暗和淡黄色位置生成的C代码Cython:
是否可以在不使用类型提示/注释的情况下对 python3 代码进行 cythonize?
我正在尝试对一个小型 python3 代码库进行 cythonize,但我遇到了一些问题,因为代码中的某些类型提示不正确,这在尝试运行 cythonized 代码时会导致问题。
这是一个简化的例子,
a.py
def test_func(arg1) -> str:
return {"hello": "world"}
Run Code Online (Sandbox Code Playgroud)
运行 cythonize 后尝试运行代码时出现错误
TypeError: Expected unicode, got dict
Run Code Online (Sandbox Code Playgroud)
如果我删除注释,一切都会正常-> str。那么,有没有办法告诉 cython 忽略所有注释?
我知道解决此问题的正确方法是修复类型提示,但我在修复注释时试图找到替代解决方案。
这是我的setup.py
#cython: language_level=3
#cython: annotation_typing=False
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
setup(
name="lib",
ext_modules=cythonize(
[
Extension("pkg1.*", ["pkg1/*.py"], include_dirs = ["."], extra_compile_args = ['-O3']),
],
build_dir="build",
compiler_directives=dict(
always_allow_keywords=True,
language_level=3)),
cmdclass=dict(
build_ext=build_ext
),
packages=["pkg1"]
)
Run Code Online (Sandbox Code Playgroud)
谢谢。
这是一个嵌套循环,其中内部索引取决于外部索引,具有以下参数:
f = rand(1,70299)
nech=24*30*24
N=length(f);
xh=(1:nech)/24;
Run Code Online (Sandbox Code Playgroud)
在 MATLAB 中:
sf2(1:nech)=0.;
sf2vel(1:nech)=0.;
count(1:nech)=0.;
for i=1:nech
for j=1:N-i-1
sf2(i)=sf2(i)+(f(j+i)-f(j))^2;
count(i)=count(i)+1;
end
sf2(i)=sf2(i)/count(i);
end
Run Code Online (Sandbox Code Playgroud)
在Python中:
def structFunPython(f,N,nech):
sf2 = np.zeros(N)
count = np.zeros(N)
for i in range(nech):
indN = np.arange(1,N-i-1)
for j in indN:
sf2[i] += np.power((f[i+j]-f[j]),2)
count[i] += 1
sf2[i] = sf2[i]/count[i]
return sf2
Run Code Online (Sandbox Code Playgroud)
与赛通:
import cython
cimport numpy as np
import numpy as np
def structFun(np.ndarray f,N,nech):
cdef np.ndarray sf2 = np.zeros(N), count = np.zeros(N),
for i in range(nech):
indN …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Cython 中循环 2 个 2d 数组。数组具有以下形状:
ranges_1是 的 6000x3 数组int64,而ranges_2是 的 2000x2 数组int64。这个迭代需要执行10000次左右。这意味着嵌套 for 循环内的计算总数约为 2000x6000x10000 = 1200 亿次。
这是我用来生成“虚拟”数据的代码:
import numpy as np
ranges_1 = np.stack([np.random.randint(0, 10_000, 6_000), np.random.randint(0, 10_000, 6_000), np.arange(0, 6_000)], axis=1)
ranges_2 = np.stack([np.random.randint(0, 10_000, 2_000), np.random.randint(0, 10_000, 2_000)], axis=1)
Run Code Online (Sandbox Code Playgroud)
这给出了 2 个像这样的数组:
array([[6131, 1478, 0],
[9317, 7263, 1],
[7938, 6249, 2],
...,
[5153, 426, 5997],
[9164, 9211, 5998],
[1695, 1792, 5999]])
Run Code Online (Sandbox Code Playgroud)
和:
array([[ 433, 558],
[3420, 2494], …Run Code Online (Sandbox Code Playgroud) 我在 jupyter 笔记本中使用 Cython。
据我所知,Cython 编译 def 函数。
但是当我想用全局变量调用函数时,它看不到它。
有没有什么方法可以用变量调用函数?
one1 = 1
%%cython
cimport numpy as np
cdef nump(number1):
return number1 + 1
nump(one1)
Run Code Online (Sandbox Code Playgroud)
****这是示例代码,向版主展示
cython ×6
python ×6
numpy ×2
arrays ×1
cythonize ×1
distutils ×1
matlab ×1
nested-loops ×1
optimization ×1
performance ×1
python-3.x ×1
types ×1