【问题标题】:Iterating Over Rows in Python Array to Extract Column Data遍历 Python 数组中的行以提取列数据
【发布时间】:2020-05-26 07:10:47
【问题描述】:

我正在使用 Python 并希望遍历 Nx9 数组的每一行并从该行中提取某些值以与它们形成另一个矩阵。 N 值可以根据我正在阅读的文件而改变,但我在示例中使用了 N=3。我只需要每行的第 0、第 1、第 3 和第 4 个值形成一个我需要存储的数组。例如:

result = np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9],
                  [11, 12, 13, 14, 15, 16, 17, 18, 19],
                  [21, 22, 23, 24, 25, 26, 27, 28, 29]])

#Output matrix of first row should be: ([[1,2],[4,5]])
#Output matrix of second row should be: ([[11,12],[14,15]])
#Output matrix of third row should be: ([[21,22],[24,25]])

然后我应该以提取值形成的 N 个矩阵结束 - 每行的 2D 矩阵。但是,形成的矩阵显示为 3D,因此在转置和减去时,我收到错误 ValueError: operands could not be broadcast together with shapes (2,2,3) (3,2,2)。我知道不能从 (2,2,3) 中减去 (3,2,2) 矩阵,那么如何获得 N 次二维矩阵?循环会更适合吗?有什么建议吗?

import numpy as np

result = np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9],
                   [11, 12, 13, 14, 15, 16, 17, 18, 19],
                   [21, 22, 23, 24, 25, 26, 27, 28, 29]])

a = result[:, 0]
b = result[:, 1]
c = result[:, 2]
d = result[:, 3]
e = result[:, 4]
f = result[:, 5]
g = result[:, 6]
h = result[:, 7]
i = result[:, 8]
output = [[a, b], [d, e]]
output = np.array(output)
output_transpose = output.transpose()
result = 0.5 * (output - output_transpose)

【问题讨论】:

  • 你能告诉我们这在数学上应该是什么样子吗?因为很明显,您不能从 (3,2,2) 中减去 (2,2,3) 矩阵。我认为你的矩阵需要,我猜,是回文的形状才能起作用。和(2,2,3)倒过来读是不一样的。它是 (3,2,2),所以你的一般公式 aMM^-1 只能在形状为回文的矩阵上工作。
  • 请分享整个错误信息。

标签: python arrays numpy loops


【解决方案1】:
In [276]: result = np.array( 
     ...:     [ 
     ...:         [1, 2, 3, 4, 5, 6, 7, 8, 9], 
     ...:         [11, 12, 13, 14, 15, 16, 17, 18, 19], 
     ...:         [21, 22, 23, 24, 25, 26, 27, 28, 29], 
     ...:     ] 
     ...: ) 
     ...:  
     ...: a = result[:, 0] 
          ...
     ...: i = result[:, 8] 
     ...: output = [[a, b], [d, e]]                                                            
In [277]: output                                                                               
Out[277]: 
[[array([ 1, 11, 21]), array([ 2, 12, 22])],
 [array([ 4, 14, 24]), array([ 5, 15, 25])]]
In [278]: arr = np.array(output)                                                               
In [279]: arr                                                                                  
Out[279]: 
array([[[ 1, 11, 21],
        [ 2, 12, 22]],

       [[ 4, 14, 24],
        [ 5, 15, 25]]])
In [280]: arr.shape                                                                            
Out[280]: (2, 2, 3)
In [281]: arr.T.shape                                                                          
Out[281]: (3, 2, 2)

transpose 交换第一个和最后一个维度。

从选定列创建 (N,2,2) 数组的更简洁方法是:

In [282]: arr = result[:,[0,1,3,4]].reshape(3,2,2)                                             
In [283]: arr.shape                                                                            
Out[283]: (3, 2, 2)
In [284]: arr                                                                                  
Out[284]: 
array([[[ 1,  2],
        [ 4,  5]],

       [[11, 12],
        [14, 15]],

       [[21, 22],
        [24, 25]]])

由于最后 2 个维度是 2,您可以将它们转置,并取差:

In [285]: arr-arr.transpose(0,2,1)                                                             
Out[285]: 
array([[[ 0, -2],
        [ 2,  0]],

       [[ 0, -2],
        [ 2,  0]],

       [[ 0, -2],
        [ 2,  0]]])

获取 (N,2,2) 数组的另一种方法是使用矩阵索引:

In [286]: result[:,[[0,1],[3,4]]]                                                              
Out[286]: 
array([[[ 1,  2],
        [ 4,  5]],

       [[11, 12],
        [14, 15]],

       [[21, 22],
        [24, 25]]])

【讨论】:

    【解决方案2】:

    好的,这不是编码问题,而是数学问题。我为你写了一些代码,因为很明显你是一个初学者,所以你应该研究一些不熟悉的语法,这样你以后就可以避免这样的问题。您可能不会经常使用它们,但知道如何使用它们会很好,因为它总体上扩展了您对 python 语法的理解。

    首先,方便复制和粘贴的完整代码:

    import numpy as np
    
    result=np.array([[1,2,3,4,5,6,7,8,9],
                     [11,12,13,14,15,16,17,18,19],
                     [21,22,23,24,25,26,27,28,29]])
    
    output = np.array(tuple(result[:,i] for i in (0,1,3)))
    
    
    def Matrix_Operation(Matrix,Coefficient):
    
        if (Matrix.shape == Matrix.shape[::-1] 
            and isinstance(Matrix,np.ndarray)
            and isinstance(Coefficient,float)):
    
            return Coefficient*(Matrix-Matrix.transpose())
        else:
            print('The shape of you Matrix is not palindromic')
            print('You cannot substitute matrices of unequal shape')
            print('Your shape: %s'%str(Matrix.shape))
    
    print(Matrix_Operation(output,0.5))
    

    现在让我们一步一步地解释这里发生的事情:

    import numpy as np
    
    result=np.array([[1,2,3,4,5,6,7,8,9],
                     [11,12,13,14,15,16,17,18,19],
                     [21,22,23,24,25,26,27,28,29]])
    

    Python 使用缩进(对齐空格)作为其语法的一个组成部分。但是,如果您提供括号,很多时候您不需要对齐缩进来让解释器理解您的代码。如果您手动提供大量值,通常建议在逗号处开始新行(此处,逗号分隔子列表)。它只是更具可读性,这样您的数据就不会在您的编码程序中脱离屏幕。

    output = np.array(tuple(result[:,i] for i in (0,1,3)))
    

    列表推导在 python 中很重要,对于脏单行器来说非常方便。据我所知,没有其他语言可以为您提供此选项。这就是 python 如此出色的原因之一。我基本上创建了一个列表列表,其中每个子列表是 (0,1,3) 中每个 i 的结果 [:,i]。这被转换为元组(是的,列表推导也可以用元组完成,而不仅仅是列表)。最后我将它包装在 np.array 函数中,因为这是我们稍后的数学运算所需的类型。

    def Matrix_Operation(Matrix,Coefficient):
    
        if (Matrix.shape == Matrix.shape[::-1] 
            and isinstance(Matrix,np.ndarray)
            and isinstance(Coefficient,(float,int))):
    
            return Coefficient*(Matrix-Matrix.transpose())
        else:
            print('The shape of you Matrix is not palindromic')
            print('You cannot substitute matrices of unequal shape')
            print('Your shape: %s'%str(Matrix.shape))
    
    print(Matrix_Operation(output,0.5))
    

    如果您要在 python 代码中创建一个复杂的公式,为什么不将它包装在一个可抽象的函数中呢?你也可以在一个函数中加入很多“质量控制”,以检查它是否为它应该执行的任务提供了正确的输入。

    您的代码失败了,因为您试图从 (3,2,2) 矩阵中减去 (2,2,3) 形状的矩阵。所以我们需要一个代码 sn-p 来检查我们提供的矩阵是否具有回文形状。您可以通过执行Container[::-1] 来颠倒容器中项目的顺序,因此我们询问是否 Matrix.shape == Matrix.shape[::-1]。此外,如果我们的系数是数字,我们的矩阵必须是np.ndarray。这就是我使用isinstance() 函数所做的事情。您可以一次检查多种类型,这就是为什么 isinstance(Coefficient,(float,int)) 包含一个包含 int 和 float 的元组。

    现在我们已经确保我们的输入是有意义的,我们可以执行我们的 Matrix_Operation。 所以总结一下:在寻求帮助之前检查你的数学是否可靠,因为这里的人可能会对这种事情感到非常恼火。您现在可能已经注意到有人已经对您的问题投了反对票。就个人而言,我认为有必要让新手在进入最佳状态之前问几个愚蠢的问题,但我想这就是投票按钮的用途。

    【讨论】:

    • 感谢您的回复,感谢您的帮助。我会稍微修改我的问题,因为我认为我提出的方式令人困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多