二维数组的numpy 3d张量
numpy 3d tensor by 2d array
我有一个稀疏矩阵。我知道 每列有两个非零值 ,所以我想 compress (删除零)使用定义为排列列表的张量矩阵。
我有
src = np.array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
我想要
trg = np.array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])
这是相同的矩阵,但没有零。
我已经硬编码了选择非零值的张量
p = np.array([
[[1,0,0,0],[0,0,1,0]],
[[1,0,0,0],[0,1,0,0]],
[[0,1,0,0],[0,0,1,0]],
[[1,0,0,0],[0,1,0,0]],
[[1,0,0,0],[0,0,0,1]]
])
我可以遍历 p
和 src
得到 trg
>>> for i in range(len(p)):
>>> print(p[i] @ src[:,i])
[2 1]
[9 1]
[8 3]
[2 8]
[4 7]
我如何用 numpy 的方式(即没有循环)?我已经尝试 tensordot
并转置我的矩阵,但没有成功。
你可以使用面具:
mask = src != 0
src[mask] #array without the zeroes but 1d
n_cols = src.shape[1]
tgt = src[mask].reshape(-1,n_cols)
此方法需要将 1d 数组重新整形为 2d,我决定保留相同数量的列,但在某些情况下,您的数组可能不是 "reshapable" 到 2d。
由于行优先排序,我们可以使用转置版本 index
具有非零掩码的数组,然后重塑 -
out = src.T[src.T!=0].reshape(src.shape[1],-1).T
样本运行-
In [19]: src
Out[19]:
array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
In [20]: src.T[src.T!=0].reshape(src.shape[1],-1).T
Out[20]:
array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])
这是一种方法:
import numpy as np
src = np.array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
# Masked indices of non-zero positions
idx = np.arange(len(src))[:, np.newaxis] * (src != 0)
# Sort to and pick valid indices at the end
idx = np.sort(idx, axis=0)[-2:]
# Get values
trg = src[idx, np.arange(src.shape[1])]
print(trg)
输出:
[[2 9 8 2 4]
[1 1 3 8 7]]
使用np.where
的解决方案:
src[np.where(src.T)[::-1]].reshape(2, -1, order='F')
事情是这样的:
np.where
使用转置给出非零元素的索引,因此无需进一步测量即可正确排序,
- 使用
[::-1]
反转顺序,因为由于转置,行和列索引被交换,
- 应用advanced indexing获取元素,
- 最后,重塑。
输出:
array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])
我有一个稀疏矩阵。我知道 每列有两个非零值 ,所以我想 compress (删除零)使用定义为排列列表的张量矩阵。
我有
src = np.array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
我想要
trg = np.array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])
这是相同的矩阵,但没有零。
我已经硬编码了选择非零值的张量
p = np.array([
[[1,0,0,0],[0,0,1,0]],
[[1,0,0,0],[0,1,0,0]],
[[0,1,0,0],[0,0,1,0]],
[[1,0,0,0],[0,1,0,0]],
[[1,0,0,0],[0,0,0,1]]
])
我可以遍历 p
和 src
得到 trg
>>> for i in range(len(p)):
>>> print(p[i] @ src[:,i])
[2 1]
[9 1]
[8 3]
[2 8]
[4 7]
我如何用 numpy 的方式(即没有循环)?我已经尝试 tensordot
并转置我的矩阵,但没有成功。
你可以使用面具:
mask = src != 0
src[mask] #array without the zeroes but 1d
n_cols = src.shape[1]
tgt = src[mask].reshape(-1,n_cols)
此方法需要将 1d 数组重新整形为 2d,我决定保留相同数量的列,但在某些情况下,您的数组可能不是 "reshapable" 到 2d。
由于行优先排序,我们可以使用转置版本 index
具有非零掩码的数组,然后重塑 -
out = src.T[src.T!=0].reshape(src.shape[1],-1).T
样本运行-
In [19]: src
Out[19]:
array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
In [20]: src.T[src.T!=0].reshape(src.shape[1],-1).T
Out[20]:
array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])
这是一种方法:
import numpy as np
src = np.array([[2, 9, 0, 2, 4],
[0, 1, 8, 8, 0],
[1, 0, 3, 0, 0],
[0, 0, 0, 0, 7]])
# Masked indices of non-zero positions
idx = np.arange(len(src))[:, np.newaxis] * (src != 0)
# Sort to and pick valid indices at the end
idx = np.sort(idx, axis=0)[-2:]
# Get values
trg = src[idx, np.arange(src.shape[1])]
print(trg)
输出:
[[2 9 8 2 4]
[1 1 3 8 7]]
使用np.where
的解决方案:
src[np.where(src.T)[::-1]].reshape(2, -1, order='F')
事情是这样的:
np.where
使用转置给出非零元素的索引,因此无需进一步测量即可正确排序,- 使用
[::-1]
反转顺序,因为由于转置,行和列索引被交换, - 应用advanced indexing获取元素,
- 最后,重塑。
输出:
array([[2, 9, 8, 2, 4],
[1, 1, 3, 8, 7]])