gpt4 book ai didi

python - numpy:压缩 block 矩阵

转载 作者:行者123 更新时间:2023-11-28 22:31:37 27 4
gpt4 key购买 nike

考虑一个矩阵 M1 为所有组合 x,y 提供值。考虑一个分区 f(x)->X 和一个分区 g(y)->Y。此外考虑对一组 A 的数字进行 p(A) 操作,即 max(A)sum(A).

映射 f,g 可用于从 M1 创建 block 矩阵 M2 其中所有 x映射到相同 X 的是相邻的,并且对于所有 y 都是相同的。

这个矩阵 M2 有一个 block 用于“集合”X,Y 的每个组合。

现在我想通过在每个 block 上分别应用 p 将这个矩阵 M2 压缩成另一个矩阵 M3M3X,Y 的每个组合都有一个值。

理想情况下,我想跳过使用 fgM1 转换为 M2飞。

执行此类操作的最有效方法是什么?是否可以为其部署 numpyscipy

特例: 实际上,在我的例子中,xy 是相同的,只有一个函数 f 适用于他们两个。我只关心 M2 中对角线下方的部分。

最佳答案

我能想到的最直接的方法,虽然可能不是最有效的(特别是如果你的矩阵很大),是将你的矩阵转换为一维数组,然后为分区提供相应的数组组索引 XY。然后,您可以按分区组索引进行分组,最后将矩阵重组回其原始形式。

例如,如果你的矩阵是

>>> M1 = np.arange(25).reshape((5,5))
>>> M1
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])

你的分区是

>>> def f(x):
... return np.array([1,1,1,2,2])[x]
>>> def g(y):
... return np.array([3,4,4,4,5])[y]

从那时起,有几种方法可以实现 reshape 和后续分组。你可以用 Pandas 来做,例如,通过构造一个 DataFrame 并使用其 stack() 方法将所有行“堆叠”在单个列中,并按其原始索引行和列索引。

>>> st = pd.DataFrame(M1).stack().to_frame('M1')
>>> st
M1
0 0 0
1 1
2 2
3 3
4 4
1 0 5
...
4 3 23
4 24

(为了便于阅读,我截断了输出,我相信如果您想查看这些示例的输出,您可以自己评估这些示例的其余部分。)然后您可以添加代表分区组索引的列:

>>> st['X'] = f(st.index.get_level_values(0))
>>> st['Y'] = g(st.index.get_level_values(1))

然后您可以按这些索引进行分组并应用您选择的聚合函数。

>>> stp = st.groupby(['X', 'Y']).agg(p)

您必须定义 p(或查找现有定义),使其采用一维 Numpy 数组并返回单个数字。如果你想使用像 sum() 这样的东西,你可以只使用 st.groupby(...).sum() 因为 Pandas 有内置的支持和其他一些标准函数,但是 agg 是通用的,适用于您可以提供的任何缩减函数 p

最后,unstack() 方法会将 DataFrame 转换回正确的二维“矩阵形式”,然后如果您愿意,可以使用 as_matrix()将其变回纯 Numpy 数组的方法。

>>> M3 = stp.unstack().as_matrix()
>>> M3
array([[ 15, 63, 27],
[ 35, 117, 43]])

如果您不想引入 Pandas,还有其他库可以做同样的事情。你可能会看看 numpy-groupies , 例如。然而,我还没有找到任何库进行真正的二维分组,如果你正在处理非常大的矩阵,你可能需要它,大到有额外的 2 或 3 个副本会耗尽可用内存。

关于python - numpy:压缩 block 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41488641/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com