如何指定包含字符串的ndarray的内存视图?
char[:]
,char*[:]
,......不起作用。
为了说明,我的问题是函数abc(...)
的定义:
cdef void abc(char[:] in_buffer):
cdef char * element
element = address(in_buffer[1])
...
def main():
cdef Py_ssize_t i, n = 100
a = np.array(['ABC', 'D', 'EFGHI'])
for i in range(n):
abc(a)
如果无法访问内存视图,我可以自己实现直接阵列访问吗?我需要避免功能abc(...)
的GIL。
编辑1:回应Bi Rico的回答。
我的目标是为函数abc(...)
释放GIL,并在其中使用c字符串函数处理ndarray in_buffer
的字符串元素。即如下所示:
cdef void abc(char[:, ::1] in_buffer) nogil:
cdef int max_elt_length = in_buffer.shape[1]+1
cdef char element[max_elt_length+1]
cdef int length
for i in range(in_buffer.shape[0]+1): # is this equivalent to in_buffer.dtype.itemsize + 1 ?
element[max_elt_length] = 0 # add null-terminator for full-size elements
memcpy(element, address(buffer[i, 0]), max_length)
length = strlen(element)
...
答案 0 :(得分:5)
问题是numpy数组dtypes必须具有固定大小。当你创建一个“字符串”数组时,你实际上是在制作一个固定长度字符数组的数组。试试这个:
import numpy as np
array = np.array(["cat", "in", "a", "hat"])
array[2] = "Seuss"
print(array)
# ['cat' 'in' 'Seu' 'hat']
print(array.dtype)
# dtype('|S3')
print(array.dtype.itemsize)
# 3
考虑到这一点,你可以这样:
cdef void abc(char[:, ::1] in_buffer):
cdef char * element
element = address(in_buffer[1, 0])
然后,当您将数组传递给abc
时,您需要执行以下操作:
a = np.array(['ABC', 'D', 'EFGHI'])
array_view = a.view('uint8').reshape(a.size, a.dtype.itemsize)
abc(array_view)
这只是一种方法,但这是我建议的,而不了解你想要做的更多。