Python 具有可变大小矩阵输入的Cython函数
我试图将本机python函数的一部分转换为cython,以提高计算时间。我想为占用时间的循环组件编写一个cython函数(正如ipythonlprun善意地告诉我的那样)。但是,此函数接受大小可变的矩阵。。我看不出如何让静态类型的cython轻松理解这一点Python 具有可变大小矩阵输入的Cython函数,python,numpy,cython,Python,Numpy,Cython,我试图将本机python函数的一部分转换为cython,以提高计算时间。我想为占用时间的循环组件编写一个cython函数(正如ipythonlprun善意地告诉我的那样)。但是,此函数接受大小可变的矩阵。。我看不出如何让静态类型的cython轻松理解这一点 for index1 in range(0,num_products): for index2 in range(0,num_products): cond_prob = (data[index1] * data[in
for index1 in range(0,num_products):
for index2 in range(0,num_products):
cond_prob = (data[index1] * data[index2]).sum() / max(col_sums[index1], col_sums[index2])
prox[index1][index2] = cond_prob
这个问题是num_产品每年都在变化,因此矩阵(数据)大小是可变的
这里最好的策略是什么
你试过在numpy中去掉for循环吗 例如,对于等式的第一部分,您可以尝试:
(data[ np.newaxis,:] * data[:,np.newaxis]).sum(2)
如果内存有问题,还可以使用np.einsum()函数。
对于第二部分,如果您还没有尝试过的话,您可能还可以编写一个numpy表达式(有点困难)。您尝试过去掉numpy中的For循环吗 例如,对于等式的第一部分,您可以尝试:
(data[ np.newaxis,:] * data[:,np.newaxis]).sum(2)
如果内存有问题,还可以使用np.einsum()函数。
对于第二部分,如果您还没有尝试过,您可能还可以编写一个numpy表达式(稍微困难一些)。Cython代码(策略上)是静态类型的,但这并不意味着数组必须具有固定的大小。在C语言中,将多维数组传递给函数可能有点尴尬,但在Cython中,您应该能够执行以下操作:
注意,我从您的
另一方面,如果您使用正确的函数和一些广播,那么使用justnumpy解决这个问题也应该相当快。事实上,由于计算复杂度主要取决于矩阵乘法,我发现下面的代码比上面的Cython代码快得多(np.inner
使用高度优化的BLAS例程):
Cython代码(策略上)是静态类型的,但这并不意味着数组必须具有固定的大小。在C语言中,将多维数组传递给函数可能有点尴尬,但在Cython中,您应该能够执行以下操作:
注意,我从您的
另一方面,如果您使用正确的函数和一些广播,那么使用justnumpy解决这个问题也应该相当快。事实上,由于计算复杂度主要取决于矩阵乘法,我发现下面的代码比上面的Cython代码快得多(np.inner
使用高度优化的BLAS例程):
嗨,在cython中,你也可以做一些事情,比如num_products=data.shape[0]或类似的事情,这样你的循环长度就会适合你。但是,我不太确定您将要改进循环的方式是否会有很大帮助,因为您正在cython循环中使用numpy函数。在numpy,你想做的似乎也很直截了当。。。上面的表达式是您的原始python代码吗?因为如果是,您可以通过省去for循环来优化它,从而使它更快。几个问题:数组
数据和prox的形状是什么?它们都是numpy阵列吗?num_products
通常有多大?谢谢您的评论。很好的观点是:矢量化而不是在numpy数组上循环!data=(170 x 800),因此prox是800 x 800Hi,同样在cython中,您可以执行num_products=data.shape[0]或类似操作,这样循环的长度将适合您。但是,我不太确定您将要改进循环的方式是否会有很大帮助,因为您正在cython循环中使用numpy函数。在numpy,你想做的似乎也很直截了当。。。上面的表达式是您的原始python代码吗?因为如果是,您可以通过省去for循环来优化它,从而使它更快。几个问题:数组数据和prox的形状是什么?它们都是numpy阵列吗?num_products
通常有多大?谢谢您的评论。很好的观点是:矢量化而不是在numpy数组上循环!数据=(170 x 800),因此prox是800 x 800的好主意。。。我明天会试试这个,并更新这个伟大的想法。。。我明天会试试这个,并更新这篇博文。。。我已经用你的Cython更新了后续问题()Function@sanguineturtle,同时我编辑了我的答案:事实证明,禁用Cython函数的边界检查可以显著提高性能。我还发现普通的Numpy更快,你一定要看看:)
很好的解释re:Cython。。。我已经用你的Cython更新了后续问题()Function@sanguineturtle,同时我编辑了我的答案:事实证明,禁用Cython函数的边界检查可以显著提高性能。我还发现普通Numpy的速度更快,你一定要看看:)
def new(X):
CS = np.sum(X, axis=1, keepdims=True)
D = np.inner(X,X) / np.maximum(CS, CS.T)
return D