【问题标题】:Apply dynamical function to each point in phase space (represented by a 2D matrix)将动态函数应用于相空间中的每个点(由二维矩阵表示)
【发布时间】:2019-11-06 14:19:54
【问题描述】:

我有一个整数矩阵phase_space,形状为(n,n),其中每个条目代表空间中该位置的点数。我还有两个更新矩阵u_x, u_y,形状也是(n,n),整数在0,...,n 范围内,指定我的动态系统在空间中的每个对应点的位置。 我想迭代地将更新矩阵“应用”到相空间。

例如,如果

>>>u_x
array([[1, 2, 1],
       [0, 1, 2],
       [0, 0, 0]])
>>>u_y
array([[2, 1, 2],
       [1, 0, 1],
       [2, 2, 0]])
>>>phase_space 
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

我想要

>>>new_phase_space
array([[1., 1., 2.],
       [1., 0., 2.],
       [0., 2., 0.]])

我当前(工作)的解决方案是循环如下

for i in range(n):
    for j in range(n):
        new_phase_space[u_x[i, j], u_y[i, j]] += phase_space[i,j] 

有什么办法可以矢量化吗?

【问题讨论】:

    标签: python numpy vectorization


    【解决方案1】:

    我们可以使用np.bincount -

    M,N = u_x.max()+1,u_y.max()+1
    ids = u_x*N+u_y
    out = np.bincount(ids.ravel(),phase_space.ravel(),minlength=M*N).reshape(M,N)
    

    在更通用的设置上运行示例 -

    In [14]: u_x
    Out[14]: 
    array([[1, 2, 1],
           [0, 1, 4],
           [0, 0, 0]])
    
    In [15]: u_y
    Out[15]: 
    array([[2, 1, 2],
           [6, 0, 1],
           [2, 6, 0]])
    
    In [17]: phase_space
    Out[17]: 
    array([[1, 1, 1],
           [5, 1, 1],
           [1, 1, 1]])
    
    In [18]: out
    Out[18]: 
    array([[1., 0., 1., 0., 0., 0., 6.],
           [1., 0., 2., 0., 0., 0., 0.],
           [0., 1., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0., 0.],
           [0., 1., 0., 0., 0., 0., 0.]])
    

    我们还可以使用稀疏矩阵,尤其是在内存是一个问题时 -

    from scipy.sparse import csr_matrix,coo_matrix
    
    out = coo_matrix( (phase_space.ravel(), (u_x.ravel(), u_y.ravel())), shape = (M,N))
    

    输出将是一个稀疏矩阵。要转换为密集型,请使用out.toarray()

    【讨论】:

    • 效果很好。谢谢!
    【解决方案2】:

    您可以使用pandas.DataFrame.groupby() 来累积phase_space 中所有坐标相同的移动:

    new_phase_space + (pd.DataFrame(phase_space)
               .stack()
               .groupby([u_x.ravel(), u_y.ravel()])
               .sum()
               .unstack(fill_value=0)
               .values
    )
    

    输出:

    array([[2., 2., 4.],
           [2., 0., 4.],
           [0., 4., 0.]])
    

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 2016-08-13
      相关资源
      最近更新 更多