Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该为可以在cython中运行时创建的numpy数组分配内存吗?_Python_Cython - Fatal编程技术网

Python 我应该为可以在cython中运行时创建的numpy数组分配内存吗?

Python 我应该为可以在cython中运行时创建的numpy数组分配内存吗?,python,cython,Python,Cython,运行平稳且快速: solexa_scores = '!"#$%&' + "'()*+,-./0123456789:;<=>?@ABCDEFGHI" cdef np.ndarray[np.uint32_t, ndim=2] sums = np.zeros(shape=(length, len(solexa_scores)+33), dtype=np.uint32) cdef bytes line cdef str decoded_line c

运行平稳且快速:

solexa_scores = '!"#$%&' + "'()*+,-./0123456789:;<=>?@ABCDEFGHI"

cdef np.ndarray[np.uint32_t, ndim=2] sums = np.zeros(shape=(length, len(solexa_scores)+33), dtype=np.uint32) 

cdef bytes line
cdef str decoded_line
cdef int counter=0 # Useful to know if it's the 3rd or 4th line of the current sequence in fastq.
with gzip.open(file_in, "rb") as f:
    for line in f:
    
        if counter%4==0: # first line of the sequence (obtain tile info)
            counter=0
    
        elif counter%3==0: # 3rd line of the sequence (obtain the qualities)
            decoded_line = line.decode('utf-8')
            for n in range(len(decoded_line)): #     enumerate(line.decode('utf-8')):
                sums[n, ord(decoded_line[n])] +=1
                
        counter+=1
solexa_得分='!"#$%&' + "'()*+,-./0123456789:;?@ABCDEFGHI“
cdef np.ndarray[np.uint32_t,ndim=2]和=np.0(形状=(长度,长度(solexa_分数)+33),数据类型=np.uint32)
字节行
cdef str解码_线
cdef int counter=0#有助于了解它是fastq中当前序列的第3行还是第4行。
使用gzip.open(文件在“rb”中)作为f:
对于f中的行:
如果计数器%4==0:#序列的第一行(获取磁贴信息)
计数器=0
elif计数器%3==0:#序列的第三行(获取质量)
decoded_line=line.decode('utf-8')
对于范围内的n(len(解码的_行)):#枚举(line.decode('utf-8')):
和[n,ord(解码的_行[n])]+=1
计数器+=1
这里numpy-ndarray和包含结果

但是,我需要字典中未知数量的数组(命名为tiles),而不是单个numpy数组,这是应该实现我的目标的代码:

solexa_scores = '!"#$%&' + "'()*+,-./0123456789:;<=>?@ABCDEFGHI"

cdef dict tiles = {} # each tile will have it's own 'sums' numpy array

cdef bytes line
cdef str decoded_line
cdef str tile

cdef int counter=0 # Useful to know if it's the 3rd or 4th line of the current sequence in fastq.
with gzip.open(file_in, "rb") as f:
    for line in f:

        if counter%4==0: # first line of the sequence (obtain tail info)
            decoded_line = line.decode('utf-8')
            tile = decoded_line.split(':')[4]
            if tile != tile_specific and tile not in tiles.keys(): # tile_specific is mentiones elsewhere. 
                tiles[tile] = np.zeros(shape=(length, len(solexa_scores)+33), dtype=np.uint32)

            counter=0

        elif counter%3==0: # 3rd line of the sequence (obtain the qualities)
            decoded_line = line.decode('utf-8')
            for n in range(len(decoded_line)): #     enumerate(line.decode('utf-8')):
                tiles[tile][n, ord(decoded_line[n])] +=1
                
        counter+=1
solexa_得分='!“#$%”和“+”()*+,-./0123456789:;?@ABCDEFGHI”
cdef dict tiles={}#每个tile都有自己的“sums”numpy数组
字节行
cdef str解码_线
cdef str瓷砖
cdef int counter=0#有助于了解它是fastq中当前序列的第3行还是第4行。
使用gzip.open(文件在“rb”中)作为f:
对于f中的行:
如果计数器%4==0:#序列的第一行(获取尾部信息)
decoded_line=line.decode('utf-8')
平铺=已解码的_行。拆分(':')[4]
如果瓷砖!=tile_specific和tile not in tiles.keys():#tile_specific在其他地方提到。
tiles[tile]=np.zero(shape=(长度,len(solexa_分数)+33),dtype=np.uint32)
计数器=0
elif计数器%3==0:#序列的第三行(获取质量)
decoded_line=line.decode('utf-8')
对于范围内的n(len(解码的_行)):#枚举(line.decode('utf-8')):
tiles[tile][n,ord(解码线[n])]+=1
计数器+=1
在第二个示例中,我不知道字典平铺中的键的数量,因此,numpy数组将在运行时声明和初始化(如果我错了或使用了错误的术语,请纠正我)。 Cython在使用numpy数组的Cython声明时没有翻译/编译,因此,我将其保留为
tiles[tile]=np.zero(shape=(length,len(solexa_分数)+33),dtype=np.uint32)
。 由于两个代码段之间共享的代码的所有其他cython优化都很好,所以我认为这个numpy数组声明就是问题所在

我该怎么解决呢,该手册指出了动态分配内存的方法,但我不知道这是如何与numpy阵列一起工作的,以及我是否应该这样做


谢谢大家!

我会忽略关于动态分配内存的文档。这并不是您想要做的——这在C级别非常重要,您正在处理Python对象

您可以轻松地多次重新分配类型为Numpy数组(或更新类型的memoryview)的变量,以便它引用不同的Numpy数组。我怀疑你想要的是什么

# start of function
cdef np.ndarray[np.uint32_t, ndim=2] tile_array

# in "if counter%4==0":
if tile != tile_specific and tile not in tiles.keys(): # tile_specific is mentiones elsewhere. 
    tiles[tile] = np.zeros(shape=(length, len(solexa_scores)+33), dtype=np.uint32)
tile_array = tiles[tile]  # not a copy! Just two references to exactly the same object

# in "if counter%3==0"
tile_array[n, ord(decoded_line[n])] +=1

仅仅为了做一些类型检查,
tile\u array=tiles[tile]
的成本很小,因此可能只有在每次分配之间使用
tile\u array
几次才值得(很难准确猜出阈值是多少,但根据当前版本计时).

我不完全理解为什么速度更快,但对于相同的输入数据,它现在只需17秒就可以完成。非常感谢。我希望我能很快理解memoryview的概念。Cython最快的事情是索引数组的各个元素:例如
tile\u数组[n,ord(decoded\u line[n])]+=1
。这将从两个相当慢的Python调用(一个用于get,一个用于设置元素)更改为一个快速的C操作。为此,Cython需要知道数组的类型。这就是为什么速度要快得多。