gpt4 book ai didi

python - 如何使用 numpy/pandas 计算 "submatrix"条目的总和?

转载 作者:太空狗 更新时间:2023-10-30 01:45:31 25 4
gpt4 key购买 nike

我在 Python 中有以下 8x8 矩阵,我将其表示为 8×8 numpy 数组或 pandas DataFrame:

import numpy as np
import pandas as pd

x = range(64)

x = np.reshape(x,(8,8))

print(x)

# [[ 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 25 26 27 28 29 30 31]
# [32 33 34 35 36 37 38 39]
# [40 41 42 43 44 45 46 47]
# [48 49 50 51 52 53 54 55]
# [56 57 58 59 60 61 62 63]]

df = pd.DataFrame(x)

print(df)

# 0 1 2 3 4 5 6 7
# 0 0 1 2 3 4 5 6 7
# 1 8 9 10 11 12 13 14 15
# 2 16 17 18 19 20 21 22 23
# 3 24 25 26 27 28 29 30 31
# 4 32 33 34 35 36 37 38 39
# 5 40 41 42 43 44 45 46 47
# 6 48 49 50 51 52 53 54 55
# 7 56 57 58 59 60 61 62 63

如果它是一个 2×2 矩阵,我正在尝试计算值的总和,并用这个总和替换上面的值。我的最终结果是

#      0   1   2   3   4   5   6   7
# 0 216 216 216 216 280 280 280 280
# 1 216 216 216 216 280 280 280 280
# 2 216 216 216 216 280 280 280 280
# 3 216 216 216 216 280 280 280 280
# 4 728 728 728 728 792 792 792 792
# 5 728 728 728 728 792 792 792 792
# 6 728 728 728 728 792 792 792 792
# 7 728 728 728 728 792 792 792 792

所以,顶角矩阵的计数为 216,因为

0+1+2+3+8+9+10+11+16+17+18+19+24+25+26+27=216

同样,

32+33+34+35+40+41+42+43+48+49+50+51+56+57+58+59=728
4+5+6+7+12+13+14+15+20+21+22+23+28+29+30+31=280
36+37+38+39+44+45+46+47+52+53+54+55+60+61+62+63=792

是否有 numpy/pandas 功能可以使这个计算更容易?特别是对于更大的矩阵,手动设置“求和矩阵”的坐标可能会非常麻烦。

最佳答案

使用 NumPy 的一种方法是:

import numpy as np

def as_submatrices(x, rows, cols=None, writeable=False):
from numpy.lib.stride_tricks import as_strided
if cols is None: cols = rows
x = np.asarray(x)
x_rows, x_cols = x.shape
s1, s2 = x.strides
if x_rows % rows != 0 or x_cols % cols != 0:
raise ValueError('Invalid dimensions.')
out_shape = (x_rows // rows, x_cols // cols, rows, cols)
out_strides = (s1 * rows, s2 * cols, s1, s2)
return as_strided(x, out_shape, out_strides, writeable=writeable)

def sum_submatrices(x, rows, cols=None):
if cols is None: cols = rows
x = np.asarray(x)
x_sub = as_submatrices(x, rows, cols)
x_sum = np.sum(x_sub, axis=(2, 3))
x_rows, x_cols = x.shape
return np.repeat(np.repeat(x_sum, rows, axis=0), cols, axis=1)

x = np.arange(64).reshape((8, 8))

print(sum_submatrices(x, 4))
# [[216 216 216 216 280 280 280 280]
# [216 216 216 216 280 280 280 280]
# [216 216 216 216 280 280 280 280]
# [216 216 216 216 280 280 280 280]
# [728 728 728 728 792 792 792 792]
# [728 728 728 728 792 792 792 792]
# [728 728 728 728 792 792 792 792]
# [728 728 728 728 792 792 792 792]]

print(sum_submatrices(x, 2))
# [[ 18 18 26 26 34 34 42 42]
# [ 18 18 26 26 34 34 42 42]
# [ 82 82 90 90 98 98 106 106]
# [ 82 82 90 90 98 98 106 106]
# [146 146 154 154 162 162 170 170]
# [146 146 154 154 162 162 170 170]
# [210 210 218 218 226 226 234 234]
# [210 210 218 218 226 226 234 234]]

print(sum_submatrices(x, 2, 8))
# [[120 120 120 120 120 120 120 120]
# [120 120 120 120 120 120 120 120]
# [376 376 376 376 376 376 376 376]
# [376 376 376 376 376 376 376 376]
# [632 632 632 632 632 632 632 632]
# [632 632 632 632 632 632 632 632]
# [888 888 888 888 888 888 888 888]
# [888 888 888 888 888 888 888 888]]

编辑: As pointed out by Divakar , np.broadcast_tonp.repeat 更快在这里,所以上面函数的改进版本是:

def sum_submatrices(x, rows, cols=None):
if cols is None: cols = rows
x = np.asarray(x)
x_sub = as_submatrices(x, rows, cols)
x_sum = np.sum(x_sub, axis=(2, 3), keepdims=True)
x_sum = np.broadcast_to(x_sum, x_sub.shape)
return x_sum.transpose((0, 2, 1, 3)).reshape(x.shape)

这与 Divakar 的答案基本相同,只是后者更好,因为它不使用跨步技巧和转置。

关于python - 如何使用 numpy/pandas 计算 "submatrix"条目的总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51825969/

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