给定一个形状为 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_full
和 A_part
。 A_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/