【问题标题】:How to make numpy.cumsum start after the first value如何使 numpy.cumsum 在第一个值之后开始
【发布时间】:2015-01-31 05:55:42
【问题描述】:

我有:

import numpy as np

position = np.array([4, 4.34, 4.69, 5.02, 5.3, 5.7, ..., 4])
x = (B/position**2)*dt

A = np.cumsum(x)
assert A[0] == 0  # I want this to be true.

其中Bdt 是标量常量。这是针对初始条件为A[0] = 0 的数值积分问题。有没有办法设置A[0] = 0,然后为其他所有内容设置cumsum

【问题讨论】:

  • 你能用一个简短的例子吗? position = [1, 2, 3, 4] 澄清你的意思(你想要什么),因为在我看来你自己并不完全理解手头的问题。
  • 无论如何,这不适用于position 作为list,它必须是np.array...

标签: python numpy numerical-methods


【解决方案1】:

我不明白你的问题到底是什么,但你可以做一些事情来获得A[0] = 0

您可以将 A 创建一个更长的索引以将零作为第一个条目:

# initialize example data
import numpy as np
B = 1
dt = 1
position =  np.array([4, 4.34, 4.69, 5.02, 5.3, 5.7])

# do calculation
A = np.zeros(len(position) + 1)
A[1:] = np.cumsum((B/position**2)*dt)

结果:

A = [ 0.          0.0625      0.11559096  0.16105356  0.20073547  0.23633533 0.26711403]
len(A) == len(position) + 1

或者,您可以操纵计算来减去结果的第一个条目:

# initialize example data
import numpy as np
B = 1
dt = 1
position =  np.array([4, 4.34, 4.69, 5.02, 5.3, 5.7])

# do calculation
A = np.cumsum((B/position**2)*dt)
A = A - A[0]

结果:

[ 0.          0.05309096  0.09855356  0.13823547  0.17383533  0.20461403]
len(A) == len(position)

如您所见,结果有不同的长度。其中之一是您所期望的吗?

【讨论】:

    【解决方案2】:

    1D cumsum

    围绕np.cumsum 的包装器,将第一个元素设置为0

    def cumsum(pmf):
        cdf = np.empty(len(pmf) + 1, dtype=pmf.dtype)
        cdf[0] = 0
        np.cumsum(pmf, out=cdf[1:])
        return cdf
    

    示例用法:

    >>> np.arange(1, 11)
    array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
    
    >>> cumsum(np.arange(1, 11))
    array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45, 55])
    

    N-D cumsum

    np.cumsum 的包装器将第一个元素设置为 0,并适用于 N 维数组:

    def cumsum(pmf, axis=None, dtype=None):
        if axis is None:
            pmf = pmf.reshape(-1)
            axis = 0
    
        if dtype is None:
            dtype = pmf.dtype
    
        idx = [slice(None)] * pmf.ndim
    
        # Create array with extra element along cumsummed axis.
        shape = list(pmf.shape)
        shape[axis] += 1
        cdf = np.empty(shape, dtype)
    
        # Set first element to 0.
        idx[axis] = 0
        cdf[tuple(idx)] = 0
    
        # Perform cumsum on remaining elements.
        idx[axis] = slice(1, None)
        np.cumsum(pmf, axis=axis, dtype=dtype, out=cdf[tuple(idx)])
    
        return cdf
    

    示例用法:

    >>> np.arange(1, 11).reshape(2, 5)
    array([[ 1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10]])
    
    >>> cumsum(np.arange(1, 11).reshape(2, 5), axis=-1)
    array([[ 0,  1,  3,  6, 10, 15],
           [ 0,  6, 13, 21, 30, 40]])
    

    【讨论】:

      【解决方案3】:

      我完全理解你的痛苦,我想知道为什么 Numpy 不允许 np.cumsum 这样做。无论如何,虽然我真的迟到了,而且已经有另一个很好的答案,但我更喜欢这个:

      np.cumsum(np.pad(array, (1, 0), "constant"))
      

      在您的情况下,array(B/position**2)*dt。您也可以更改np.padnp.cumsum 的顺序。我只是在数组的开头添加一个零并调用np.cumsum

      【讨论】:

        【解决方案4】:

        您可以使用滚动(右移 1),然后将第一个条目设置为零。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-28
          • 2016-08-05
          • 2023-02-17
          • 1970-01-01
          • 1970-01-01
          • 2019-11-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多