Numpyic 方法从方阵的每 M 行和列中取出前 N 行和列
Numpyic way to take the first N rows and columns out of every M rows and columns from a square matrix
我有一个 20 x 20 的方阵。我想从每 5 行和列中取出前 2 行和前 2 列,这意味着输出应该是一个 8 x 8 方阵。这可以通过以下 2 个连续步骤完成:
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
B = np.asarray([row for i, row in enumerate(A) if i % m < n])
C = np.asarray([col for j, col in enumerate(B.T) if j % m < n]).T
但是,我正在寻找效率。有没有更多的 Numpyic 方法来做到这一点?我宁愿一步完成。
可以使用np.ix_
保留行/列索引小于2模5的元素:
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
mask = np.arange(20) % 5 < 2
result = A[np.ix_(mask, mask)]
print(result)
这输出:
[[ 0 1 5 6 10 11 15 16]
[ 20 21 25 26 30 31 35 36]
[100 101 105 106 110 111 115 116]
[120 121 125 126 130 131 135 136]
[200 201 205 206 210 211 215 216]
[220 221 225 226 230 231 235 236]
[300 301 305 306 310 311 315 316]
[320 321 325 326 330 331 335 336]]
与接受的答案非常相似,但可以直接参考 rows/column 索引。有兴趣看看基准是否与在接受的答案
中使用np.ix_()
有什么不同
Return 具体 Row/Column 按数字索引
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
B = np.asarray([row for i, row in enumerate(A) if i % m < n])
C = np.asarray([col for j, col in enumerate(B.T) if j % m < n]).T
rowAndColIds = list(filter(lambda x: x % m < n,range(20)))
# print(rowAndColsIds)
result = A[:,rowAndColIds][rowAndColIds]
print (result)
你可以使用索引广播
i = (np.r_[:20:5][:, None] + np.r_[:2]).ravel()
A[i[:,None], i]
输出:
array([[ 0, 1, 5, 6, 10, 11, 15, 16],
[ 20, 21, 25, 26, 30, 31, 35, 36],
[100, 101, 105, 106, 110, 111, 115, 116],
[120, 121, 125, 126, 130, 131, 135, 136],
[200, 201, 205, 206, 210, 211, 215, 216],
[220, 221, 225, 226, 230, 231, 235, 236],
[300, 301, 305, 306, 310, 311, 315, 316],
[320, 321, 325, 326, 330, 331, 335, 336]])
我有一个 20 x 20 的方阵。我想从每 5 行和列中取出前 2 行和前 2 列,这意味着输出应该是一个 8 x 8 方阵。这可以通过以下 2 个连续步骤完成:
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
B = np.asarray([row for i, row in enumerate(A) if i % m < n])
C = np.asarray([col for j, col in enumerate(B.T) if j % m < n]).T
但是,我正在寻找效率。有没有更多的 Numpyic 方法来做到这一点?我宁愿一步完成。
可以使用np.ix_
保留行/列索引小于2模5的元素:
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
mask = np.arange(20) % 5 < 2
result = A[np.ix_(mask, mask)]
print(result)
这输出:
[[ 0 1 5 6 10 11 15 16]
[ 20 21 25 26 30 31 35 36]
[100 101 105 106 110 111 115 116]
[120 121 125 126 130 131 135 136]
[200 201 205 206 210 211 215 216]
[220 221 225 226 230 231 235 236]
[300 301 305 306 310 311 315 316]
[320 321 325 326 330 331 335 336]]
与接受的答案非常相似,但可以直接参考 rows/column 索引。有兴趣看看基准是否与在接受的答案
中使用np.ix_()
有什么不同
Return 具体 Row/Column 按数字索引
import numpy as np
m = 5
n = 2
A = np.arange(400).reshape(20,-1)
B = np.asarray([row for i, row in enumerate(A) if i % m < n])
C = np.asarray([col for j, col in enumerate(B.T) if j % m < n]).T
rowAndColIds = list(filter(lambda x: x % m < n,range(20)))
# print(rowAndColsIds)
result = A[:,rowAndColIds][rowAndColIds]
print (result)
你可以使用索引广播
i = (np.r_[:20:5][:, None] + np.r_[:2]).ravel()
A[i[:,None], i]
输出:
array([[ 0, 1, 5, 6, 10, 11, 15, 16],
[ 20, 21, 25, 26, 30, 31, 35, 36],
[100, 101, 105, 106, 110, 111, 115, 116],
[120, 121, 125, 126, 130, 131, 135, 136],
[200, 201, 205, 206, 210, 211, 215, 216],
[220, 221, 225, 226, 230, 231, 235, 236],
[300, 301, 305, 306, 310, 311, 315, 316],
[320, 321, 325, 326, 330, 331, 335, 336]])