白板的微信
循环没有任何问题,但将列表附加到列表非常慢。为了避免这种情况,您可以为数据分配一个足够大的数组并在之后缩小它(或将数据复制到具有您需要的确切大小的数组中),或者您可以使用std:vector.在这个答案中我使用,Numba因为我在高性能 Cython 编码方面没有经验,但 Cython 实现应该是直接的。Numba 也有一个有限的列表和元组内部表示,但我不知道 Cython 中是否可用。例子import numpy as npimport numba as nb@nb.njit()def get_image_data_arr(image_data): array_text = np.empty((image_data.shape[0]*image_data.shape[1],2),dtype=np.int64) ii=0 for y in range(image_data.shape[0]): for x in range(image_data.shape[1]): if image_data[y, x] < 210: array_text[ii,0]=x array_text[ii,1]=y ii+=1 return array_text[:ii,:]@nb.njit()def get_image_data(image_data): list_text = [] for y in range(image_data.shape[0]): for x in range(image_data.shape[1]): if image_data[y, x] < 210: #appending lists list_text.append([x, y]) #appending tuples #list_text.append((x, y)) return list_text时间安排所有时间都没有编译开销(第一次调用函数被排除在时间之外)。#Create some dataimage_data=np.random.rand(1683*1240).reshape(1683,1240)*255image_data=image_data.astype(np.uint8)get_image_data (Pure Python) : 3.4sget_image_data (naive Numba, appending lists) : 1.1sget_image_data (naive Numba, appending tuples) : 0.3sget_image_data_arr: : 0.012snp.argwhere(image_data<210) : 0.035s
HUWWW
我建议使用 Numpy 的argwhere()函数如下:import numpy as np# Create a starting imageim = np.arange(0,255,16).reshape(4,4) 看起来像这样:array([[ 0, 16, 32, 48], [ 64, 80, 96, 112], [128, 144, 160, 176], [192, 208, 224, 240]])现在找到所有小于 210 的元素的坐标:np.argwhere(im<210) 看起来像这样:array([[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1]])