【问题标题】:Calculating numpy array according to another numpy array values根据另一个numpy数组值计算numpy数组
【发布时间】:2019-06-30 22:37:10
【问题描述】:

我需要计算具有数组 D 的数组 Z(仅使用索引、切片和广播,没有循环):

D = [0, 0, 0, 0, 12, 36, 24, 24, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 36]

Z = [nan, nan, nan, nan, 12., 14.4, 15.36, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 15.8016, 15.8016, 15.8016, 15.8016, 17.8214]

规则#1:在 D 的第一个非零值之前(此处索引 数组 Z 值等于 nan(此处索引 0 到 3)

规则#2:D 的第一个非零值(此处为索引 4,值 12)=> 数组 Z 在该索引 (12) 处获取 A 的值

规则#3:遵循规则#2,如果 D 在索引 i 处不等于 0 => Z[i] = Z[i-1] + 0.1 * (D[i] - Z[i-1] )

即:

ind=4: D[4]=12 => Z[4]=12 (Rule#2)

ind=5: D[5]=36 => Z[5]=12 + 0.1 * (36 - 12) = 14.4

ind=6: D[6]=24 => Z[6]=14.4 + 0.1 * (24 - 14.4) = 15.36

ind=7: D[7]=24 => Z[7]=15.36 + 0.1 * (24 - 15.36) = 16.224

规则#4:如果 D 等于 0(此处索引 i = 8)=> Z[i] = Z[i-1]

即:

ind=8: D[8]=0 =>  D[8]=D[7]=16.224

【问题讨论】:

    标签: python numpy numpy-ndarray array-broadcasting numpy-slicing


    【解决方案1】:

    希望对你有帮助:

    def function_needed(D,alpha):
        #Rule 1
        Z=np.zeros(len(D))
        idx=(np.array(D)!=0).argmax(axis=0)
        Z[:idx] = np.NaN
        #Rule 2
        Z[idx]=D[idx]
        #Rule 3
        x=np.array(D)[np.nonzero(np.array(D))]
        n = len(x)
        y_1 = Z[idx]
        pot = (1-alpha)**np.arange(n-1, -1, -1)
        y = alpha*np.cumsum(pot * x)/pot+y_1*(1-alpha)**np.arange(1, n+1)
        Z[np.nonzero(D)]=y
        #Rule 4
        mask =(Z==0)
        idx = np.where(~mask,np.arange(mask.shape[0]),0)
        Z=Z[np.maximum.accumulate(idx,axis=0, out=idx)]
        return Z
    
    testing=function_needed(D,0.1)
    

    我开发了一个名为 function_needed 的函数来一次性制定所有规则。这是一步一步的解释

    规则 1

    1-创建一个与原数组D大小相同的0的数组

    Z=np.zeros(len(D))
    

    2- 获取第一个非零值的索引

    idx=(np.array(D)!=0).argmax(axis=0)
    

    3- 将 NaN 置于第一个非零值之前的所有值

    Z[:idx] = np.NaN
    

    规则 2

    1- 在 D 的第一个非零值的索引处用第一个非零需求填充 Z

    Z[idx]=D[idx]
    

    规则 3

    只有在非零需求时才会重新计算 Z

    1-创建X对应D非零的数组

    x=np.array(D)[np.nonzero(np.array(D))]
    

    2- 如果我们考虑 Y,则按照规则 3 中针对非零需求提出的计算。我们注意到 Y 的每个元素递归地用以下公式给出

    image of the formula

    其中 y_1 是第一个非零值

    n = len(x)
    
    y_1 = Z[idx]
    
    pot = (1-alpha)**np.arange(n-1, -1, -1)
    
    y = alpha*np.cumsum(pot * x)/pot+y_1*(1-alpha)**np.arange(1, n+1)
    
    Z[np.nonzero(D)]=y
    

    在那个阶段Z等于

    Z
    

    规则 4

    将上一步得到的0值替换为第一个次等的非零值。这就是我们所说的前向填充 这样做:

    mask =(Z==0)
    idx = np.where(~mask,np.arange(mask.shape[0]),0)
    Z=Z[np.maximum.accumulate(idx,axis=0, out=idx)]
    

    【讨论】:

    • 请在回答问题时提供代码说明。另请注意,OP 对循环说“不”
    • 我修改了第 3 条规则,并成功使其没有循环
    • 我需要花一些时间来解释基于以下帖子stackoverflow.com/questions/30068020/…的全局方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    相关资源
    最近更新 更多