在我的工作中,我经常需要聚合和扩展各种量的矩阵,并且我正在寻找最有效的方法来执行这些操作。例如,我将有一个
例如,我会有一个类似下面这样的假设的
NxN
的矩阵,我想将其从 NxN
聚合到 PxP
,其中 P < N
。这是使用较大维度和较小维度之间的对应关系完成的。通常,P
将会在100左右。例如,我会有一个类似下面这样的假设的
4x4
矩阵(但实际上,我的矩阵会大得多,约为 1000x1000
)m=np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
>>> m
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
以此类似的对应关系(示意图):
0 -> 0
1 -> 1
2 -> 0
3 -> 1
我通常将数据存储在字典中。这意味着行和列的索引0和2都被分配给新索引0,而行和列的索引1和3则被分配给新索引1。矩阵可以是任何形式,但当我想要压缩时,对应关系始终是多对一的。
如果输入矩阵为A
,输出矩阵为B
,那么单元格B[0, 0]
将是A[0, 0] + A[0, 2] + A[2, 0] + A[2, 2]
的总和,因为新索引0由原始索引0和2组成。
这里的聚合过程将导致:
array([[ 1+3+9+11, 2+4+10+12 ],
[ 5+7+13+15, 6+8+14+16 ]])
= array([[ 24, 28 ],
[ 40, 44 ]])
我可以通过创建一个正确大小的空矩阵并循环遍历初始矩阵的所有4x4=16个单元格,并在嵌套循环中累积,但这似乎是低效的,numpy的向量化特性总是被人们强调。我还使用np.ix_
创建索引集并使用m[row_indices, col_indices].sum()
来完成,但我想知道最高效的numpy方式是什么。
相反,使用对应关系扩展矩阵的明智且高效的方法是什么?例如,使用相同的对应关系但以相反的方式展开时,我将从以下情况开始:
array([[ 1, 2 ],
[ 3, 4 ]])
to
array([[ 1, 2, 1, 2 ],
[ 3, 4, 3, 4 ],
[ 1, 2, 1, 2 ],
[ 3, 4, 3, 4 ]])
这里的值只是简单地复制到新单元格中。
在尝试聚合方面,我已经使用了一些带有Pandas方法的方法,在索引和列上使用groupby
,然后使用例如df.values
提取最终矩阵。但是,我不知道如何等效地扩展矩阵,而不使用许多类似unstack
和join
等内容。而且,我看到很多人经常说使用Pandas不太时间有效。
编辑1:在评论中有人问我应该如何进行聚合。如果我使用嵌套循环和原始维度与新维度之间的字典查找,则会按以下方式执行:
>>> m=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
>>> mnew=np.zeros((2,2))
>>> big2small={0:0, 1:1, 2:0, 3:1}
>>> for i in range(4):
... inew = big2small[i]
... for j in range(4):
... jnew = big2small[j]
... mnew[inew, jnew] += m[i, j]
...
>>> mnew
array([[24., 28.],
[40., 44.]])
编辑2: 另一位评论要求在开始时更明确地阐述聚合示例,因此我已经这样做了。
np.tile(arr, [2,2])
来解决,但我不理解您的要求,因此可能不正确。 - Code Differentarray([[ 24, 28 ], [ 40, 44 ]])
重写为array([[ 1+3+9+11, etc ], [ etc,etc ]])
。 - Stef