【问题标题】:How can I apply the assignment operator correctly in Python?如何在 Python 中正确应用赋值运算符?
【发布时间】:2018-06-15 08:28:05
【问题描述】:

我必须对一个大数组进行一些数学运算(例如,加法、乘法)。 为了防止出现任何 'MemoryError' ,我正在按照thread 的答案中的建议进行计算。

但是,我在按照线程中的建议应用分配操作时遇到了一些麻烦。我将使用一个小的 3x3 数组来演示我的问题。

我有以下输入数组K

array([[ 0.        ,  0.51290339,  0.24675368],
       [ 0.51290339,  0.        ,  0.29440921],
       [ 0.24675368,  0.29440921,  0.        ]])

我想将以下计算应用于输入数组K

output = K* (1.5 - 0.5 * K* K)

我应用上述等式在 Python 中计算所需的输出,如下所示:

K*= (1.5+np.dot(np.dot(-0.5,K),K))

但是,输出的答案不正确。

我想要的答案应该是:

0.0000000 0.7018904 0.3626184
0.7018904 0.0000000 0.4288546
0.3626184 0.4288546 0.0000000

欢迎任何帮助。

【问题讨论】:

标签: python numpy


【解决方案1】:

之所以出现差异,是因为dot 计算点积,而* 计算元素乘积。尝试使用

K *= 1.5 - 0.5 * K * K

改为。

加法

不幸的是,这还没有解决内存问题。我建议使用 cython 来计算所需的函数而不分配额外的内存。

# This cython function must be compiled
def evaluate_function_inplace(double[:] values):
    cdef int i
    for i in range(values.shape[0]):
        values[i] *= 1.5 - 0.5 * values[i] * values[i]

随后,您可以像这样使用该功能。

K = ...
evaluate_function_inplace(K.ravel())

K.ravel() 调用将展平数组,但不会分配新内存。

当然,你也可以使用上面的方法而不求助于 cython,但是在 python 中迭代如此大数组的元素的性能开销非常大。

【讨论】:

  • 直到,这个解决方案适用于相对较小的阵列......我的阵列是(29000 x 29000)。当我使用上述函数时,它会给出 MemoryError。有什么建议吗?
  • 不幸的是,在某些时候您必须计算K 的平方(并将其存储在内存中)才能相乘。如果您在适当的位置计算值,则可以解决存储整个数组的需要(有关讨论,请参阅stackoverflow.com/a/6824389/1150961)。我已经使用 cython 添加了一个可能的解决方案。
  • 我正在寻找非 Cython 解决方案。
【解决方案2】:

您的问题是您实际上是在执行矩阵乘法。 在您的情况下,您想要的是以下内容:

K = (np.dot(-0.5,K) * K + 1.5) * K

【讨论】:

    【解决方案3】:

    试试这个

     K*= (1.5+np.multiply(np.multiply(-0.5,K),K))
    

    它给出输出

    array([[ 0.        ,  0.70189037,  0.36261843],
           [ 0.70189037,  0.        ,  0.42885459],
           [ 0.36261843,  0.42885459,  0.        ]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 2012-03-18
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      相关资源
      最近更新 更多