python - How to efficiently unroll a matrix by value with numpy?
问题描述
I have a matrix M
with values 0 through N
within it. I'd like to unroll this matrix to create a new matrix A
where each submatrix A[i, :, :]
represents whether or not M == i.
The solution below uses a loop.
# Example Setup
import numpy as np
np.random.seed(0)
N = 5
M = np.random.randint(0, N, size=(5,5))
# Solution with Loop
A = np.zeros((N, M.shape[0], M.shape[1]))
for i in range(N):
A[i, :, :] = M == i
This yields:
M
array([[4, 0, 3, 3, 3],
[1, 3, 2, 4, 0],
[0, 4, 2, 1, 0],
[1, 1, 0, 1, 4],
[3, 0, 3, 0, 2]])
M.shape
# (5, 5)
A
array([[[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[0, 0, 1, 0, 0],
[0, 1, 0, 1, 0]],
...
[[1, 0, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 0]]])
A.shape
# (5, 5, 5)
Is there a faster way, or a way to do it in a single numpy operation?
解决方案
Broadcasted comparison is your friend:
B = (M[None, :] == np.arange(N)[:, None, None]).view(np.int8)
np.array_equal(A, B)
# True
The idea is to expand the dimensions in such a way that the comparison can be broadcasted in the manner desired.
As pointed out by @Alex Riley in the comments, you can use np.equal.outer
to avoid having to do the indexing stuff yourself,
B = np.equal.outer(np.arange(N), M).view(np.int8)
np.array_equal(A, B)
# True
推荐阅读
- python - 涉及 Python 内置数字类型和 Numpy 类型 float64 和 complex128 的二进制算术运算结果的混淆类型
- python - 查找两个日期时间范围之间的缺失日期
- java - 帮助菜单中未显示 Eclipse“检查更新”、“安装新软件”和“市场”
- python - 在 Python 列中有多个级别
- python - 为什么我的 Python 文件不在 CSV 中写入多行?
- css - react如何控制其他组件的css?
- file-io - Fortran:使用“read”读取数据时检查数据格式
- typescript - TypeScript:从(内部)函数导出对象
- php - 如何按任意顺序按键对数组进行排序php 5.6
- javascript - 为什么 MutationObserver 会触发许多记录?