python - 在 Numpy 数组上计算交错/移位均值

标签 python numpy

给定一个形状为 6 x 10 的 Numpy 数组,您将如何计算对角线的移位均值?像这样的矩阵

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]

应该产生以下方式的数组

 [np.mean(0), np.mean(1, 0), np.mean(2, 1, 0), np.mean(3, 2, 1, 0), ..., np.mean(9, 8) + np.mean(9)

最佳答案

更新:比我第一次发布的方法简单得多:

>>> id_ = np.add.outer(*map(np.arange, A.shape))
>>> result = np.bincount(id_.ravel(), A.ravel()) / np.bincount(id_.ravel())

更新结束。

这是使用 as_strided 的方法:

>>> A = np.repeat(np.arange(10)[None, :], 6, axis=0)
>>> A
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> 
>>> sh_i, sh_j = A.shape
>>> st_i, st_j = A.strides
>>> 
>>> assert A.flags.c_contiguous
>>> assert sh_i <= sh_j
>>> 
>>> A_full = np.lib.stride_tricks.as_strided(A.ravel()[(sh_i-1) * sh_j:], (sh_j-sh_i+1, sh_i), (st_j, st_j-st_i))
>>> A_part = np.lib.stride_tricks.as_strided(A.ravel()[sh_i * sh_j - sh_i+1:], (sh_i-2, sh_i+1), (st_j, st_j-st_i))
>>> split = np.array((np.zeros((sh_i-2,), int), np.arange(sh_i-1, 1, -1), np.full((sh_i-2,), sh_i+1))).T
>>> full_means = A_full.mean(axis=1)
>>> part_means = A_part.cumsum(axis=1)[np.arange(sh_i-2)[:, None], split[:, 1:]-1].astype(float)
>>> part_means[:, 1] -= part_means[:, 0]
>>> part_means /= np.diff(split, axis=1)
>>> result = np.concatenate([A[0, 0, None], part_means[:, 1], full_means, part_means[:, 0], A[-1, -1, None]])
>>> 
>>> result
array([0. , 0.5, 1. , 1.5, 2. , 2.5, 3.5, 4.5, 5.5, 6.5, 7. , 7.5, 8. ,
       8.5, 9. ])

了解此处发生情况的最简单方法是检查跨步 View A_fullA_partA_full 包含全长对角线,而 A_part 包含右下角的缩减长度对角线(除了最角点)与左上角的缩减长度对角线(除了最角点)相连。

>>> A_full
array([[0, 1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5, 6],
       [2, 3, 4, 5, 6, 7],
       [3, 4, 5, 6, 7, 8],
       [4, 5, 6, 7, 8, 9]])
>>> A_part
array([[5, 6, 7, 8, 9, 0, 1],
       [6, 7, 8, 9, 0, 1, 2],
       [7, 8, 9, 0, 1, 2, 3],
       [8, 9, 0, 1, 2, 3, 4]])

split 包含右下角结束和左上角开始的位置。

>>> from pprint import pprint
>>> 
>>> split
array([[0, 5, 7],
       [0, 4, 7],
       [0, 3, 7],
       [0, 2, 7]])
>>> pprint([np.split(Ap, sp) for Ap, sp in zip(A_part, split[:, 1, None])])
[[array([5, 6, 7, 8, 9]), array([0, 1])],
 [array([6, 7, 8, 9]), array([0, 1, 2])],
 [array([7, 8, 9]), array([0, 1, 2, 3])],
 [array([8, 9]), array([0, 1, 2, 3, 4])]]

代码的其余部分使用这些位来拼凑所需的均值向量。

关于python - 在 Numpy 数组上计算交错/移位均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49204260/

相关文章:

python - 如何修复此代码,使其打印一串字母,其中一个位置被相应的输入数字替换?

python - Python 中 2 的幂的列表理解因 numpy 数组而失败

python - 将 numpy 数组与矩阵的每一行进行比较以计算相似项(矢量化)

python - 二维随机游走,Python

python - 无法让 ToMany 在 Tastypie 中工作

python - 如何忽略 Pandas 重组字符串索引?

python - 列表理解以从字典中提取元组列表

Python/Numpy - 矩阵乘以一个二维数组和另一个二维数组的每一行

python - 根据Python中其他数组中值的条件逻辑创建数组

python - 如何更改字典值中字符串中的数字?