在寻求加速 Python 时,有没有更好的方法来使用 cython?

Is there a better way to use cython when looking to speed up Python?

我有一个具有以下结构的大型 numpy 数组:

array([['A', 0.0, 0.0],
       ['B2', 1.0, 0.0],
       ['B4', 2.0, 3.0],
       ['AX1', 3.0, 1.0],
       ['C2', 0.0, 2.0],
       ['D3', 2.0, 1.0],
       ['X4', 3.0, 8.0],
       ['BN', 2.0, 9.0],
       ['VF', 12.0, 25.0],
       ['L', 1.0, 3.0],
       ...,
       ['s', 2.0, 27.0],
       ['P', 0.0, 0.0]], dtype=object)

我正在使用 cython 尝试尽可能加快处理速度。下面代码中的参数数据集就是上面的数组。

%%cython

cpdef permut1(dataset):
  cdef int i
  cdef int j
  cdef str x
  cdef str v

  xlist = []
  for i, x in enumerate(dataset[:,0]):
    for j, v in enumerate(dataset[:,0]):
      xlist.append((x,v,dataset[i][1], dataset[j][2]))
  return xlist

但是,当 运行 上面的代码有和没有 cython 时,我得到以下时间:

没有 cython:0:00:00.945872

使用 cython:0:00:00.561925

关于如何使用 cython 进一步加快速度的任何想法?

谢谢

通常使用 numpy,你想要:

  • 将相同的数据类型放入数组(避免 dtype=object 并为字符串使用单独的数组)。否则每个元素访问都必须在内部测试数据类型,这会减慢速度。 cython 也是如此。

  • 避免按元素访问,而是仅对整个数组使用操作。对于您的情况,请考虑在整数数组中构建索引并将输入数组的索引表示为一个操作。

例如:

a = np.array(..., dtype=np.float) # input number columns only from above
fa = a.flatten()  # helps to use 1d indices
far = fa.reshape((fa.shape[0], 1))  # make 2d for hstack()
idxs = np.indices((a.shape[0], a.shape[0]))
idxs1 = idxs[0].flatten()  # 0,0,0,1,1,1,...
idxs2 = idxs[1].flatten()  # 0,1,0,1,...
np.hstack((far[idxs1], far[idx2]))

不需要cython(除非你真的需要复杂的逐元素计算)。

由于您之前使用 O(n^2) 次操作进行迭代,因此即使您首先必须将输入数组转换为这种格式,上述操作也应该可以加快速度。