函数具有不同数量的For循环和不同数量的变量

时间:2019-07-01 13:23:11

标签: python python-3.x

我正在用Python 3做一些实现,我需要一些帮助。我有函数,这取决于矩阵的维数。我实际上有两个矩阵,并希望以某种方式获得第三个矩阵。例如(二维矩阵):

def my_matrix_2d(mat1, mat2):
    ar = []
    for i in range(len(mat1[0])):
        ar1 = []
        for j in range(len(mat1[1])):
            try:
                ar1.append([mat1[0][i], mat1[1][j], mat2[i][j]])
            except IndexError:
                ar1.append([mat1[0][i], mat1[1][j], None])
        ar.append(ar1)
    return ar

3维矩阵的另一个示例:

def my_matrix_3d(mat1, mat2):
    ar = []
    for i in range(len(mat1[0])):
        ar1 = []
        for j in range(len(mat1[1])):
            ar2 = []
            for k in range(len(mat1[2])):
                try:
                    ar2.append([mat1[0][i], mat1[1][j], mat1[2][k], mat2[i][j][k]])
                except IndexError:
                    ar2.append([mat1[0][i], mat1[1][j], mat1[2][k], None])
            ar1.append(ar2)
        ar.append(ar1)
    return ar

我需要对n维矩阵做一个通用函数。我知道递归一定要解决,但是我只是想不通。 我将不胜感激。

编辑:

实际上我没有很好地描述我的问题,因此我将尝试给出详细的描述。首先,我将描述2D问题。我们有两个矩阵mat1和mat2。 len(mat1)= 2,假设len(mat1 [0])= m和len(mat1 [1])= n。然后,mat2是m x n矩阵,因此对于i = 0,1,...,m-1,len(mat2)= m和len(mat2 [i])= n。 my_matrix_2d是函数,以某种方式组合了这两个矩阵。让我们看一个具体的例子:我们可以看到mat1是2D直方图的bin边缘,mat2是bin的高度,因此mat1 [0]代表x坐标的bin边缘,mat1 [1]代表y坐标的bin边缘。 mat2表示在x坐标和y坐标边缘相交处的仓高。因此,my_matrix_2d在二维直方图中存储有关箱的边缘和箱的高度的信息。它的元素是向量(mat1 [0] [i],mat1 [1] [j],mat2 [i] [j]),由于我们还需要一个边来确定垃圾箱宽度,因此最后一个向量是(mat1 [ 0] [i],mat1 [1] [j],无)。

与3D示例类似。 mat1 [0](len = m)是x坐标的bin边缘,mat1 [1](len = n)是y坐标的bin边缘,mat1 [2](len = o)是z坐标的bin边缘,而mat2是mxnxo矩阵,其中包含箱高度。 my_matrix_3d输出应为具有元素(矩阵1 [0] [i],矩阵1 [1] [j],矩阵1 [2] [k],矩阵2 [i] [j] [k])的矩阵/数组,其中i = 0,...,m-2,j = 0,...,n-2,k = 0,...,o-2,如果i = m-1或j = n-1或k = o-1,矩阵中的元素应为(mat1 [0] [i],mat1 [1] [j],mat1 [2] [k],无)。

P.S。 my_matrix_nd应该是n维矩阵,其形状与mat2相同。但是mat2中的元素是浮点数,而my_matrix_nd中的元素是len(mat1)+1个向量。

2 个答案:

答案 0 :(得分:0)

这是一个大致的递归实现,带有一个额外的参数来指定递归深度(实际上,当您说它是n维矩阵时,n是什么?):

def my_matrix_nd(mat1, mat2, depth=1):
    # base case
    if depth == 0:
        return [mat2]
    # recursive case
    ar = []
    for i in range(len(mat1[0])):
        try:
            ar.append([mat1[0][i]] + my_matrix_nd(mat1[1:], mat2[i], depth-1))
        except IndexError:
            ar.append([mat1[0][i], None])
    return ar

它使用列表切片来为每次重复都切断mat1的第一个元素,并通过一次递归地传递子列表来隔离mat2[i][j][k]。在基本情况下,它尝试仅返回mat2的焦点值(但作为单元素列表,因此我们可以在其前面加上其他参数)。然后在递归链的备份过程中,依次添加mat1的较浅元素。

答案 1 :(得分:0)

如何重塑阵列?您需要n维吗?

否则,您可以变换一维数组中的两个矩阵,构建第三个矩阵 然后重塑结果

def operate_ndim(mat1, mat2):
    shape1 = mat1.shape
    shape2 = mat2.shape

    if shape1 != shape2: return -1 # I assume that with different shapes it breaks

    dim_1d   =  np.size(mat1)

    mat1 = mat1.reshape(dim_1d)
    mat2 = mat2.reshape(dim_1d)
    res  = np.zeros(dim_1d)

    for i in range(dim_1d):
        res[i] = mat1[0] + mat2[100] + mat2[i] - mat1[-i]   # operation rule

    res = res.reshape(shape1)
    return res