First row of numpy.ones is still populated after referencing another matrix

前端 未结 5 1003
说谎
说谎 2021-01-26 10:01

I have a matrix \'A\' whose values are shown below. After creating a matrix \'B\' of ones using numpy.ones and assigning the values from \'A\' to \'B\' by indexing \'i\' rows an

5条回答
  •  感情败类
    2021-01-26 10:43

    Here first what I think you are trying to do, with minimal corrections, comments to your code:

    import numpy as np
    
    A = np.matrix([[8,8,8,7,7,6,8,2],
                   [8,8,7,7,7,6,6,7],
                   [1,8,8,7,7,6,6,6],
                   [1,1,8,7,7,6,7,7],
                   [1,1,1,1,8,7,7,6],
                   [1,1,2,1,8,7,7,6],
                   [2,2,2,1,1,8,7,7],
                   [2,1,2,1,1,8,8,7]])
    
    B = np.ones((8,8),dtype=np.int)
    
    for i in np.arange(1,9): #  i= 1...8
        for j in np.arange(1,9):  # j= 1..8, but A[8,j] and A[j,8] do not exist,
                                  # if you insist on 1-based indeces, numpy still expects 0... n-1, 
                                  # so you'll have to subtract 1 from each index to use them
            B[i-1,j-1] = A[i-1,j-1]
    
    
    C = np.zeros((6,6),dtype=np.int)
    D = np.matrix([[1,1,2,3,3,2,2,1],
                   [1,2,1,2,3,3,3,2],
                   [1,1,2,1,1,2,2,3],
                   [2,2,3,2,2,2,1,3],
                   [1,2,2,3,2,3,1,3],
                   [1,2,3,3,2,3,2,3],
                   [1,2,2,3,2,3,1,2],
                   [2,2,3,2,2,3,2,2]])
    
    
    for k in np.arange(2,8):       # k = 2..7
        for l in np.arange(2,8):   # l = 2..7   ; matrix B has indeces 0..7, so if you want inner points, you'll need 1..6
                b = B[k-1,l-1]   # so this is correct, gives you the inner matrix
                if b == 8:           # here b is  a value in the matrix , not the index, careful not to mix those
                    # Matrix C is smaller than Matrix B  ; yes C has indeces from 0..5 for k and l
                    # so to address C you'll need to subtract 2 from the k,l that you defined in the for loop
                    C[k-2,l-2] = C[k-2,l-2] + 1*D[k-1,l-1]
    
    print C
    

    output:

    [[2 0 0 0 0 0]
     [1 2 0 0 0 0]
     [0 3 0 0 0 0]
     [0 0 0 2 0 0]
     [0 0 0 2 0 0]
     [0 0 0 0 3 0]]
    

    But there are more elegant ways to do it. In particular look up slicing, ( numpy conditional array arithmetic, possibly scipy threshold.All of the below should be much faster than Python loops too (numpy loops are written in C).

    B=np.copy(A)  #if you need a copy of A, this is the way
    
    # one quick way to make a matrix that's 1 whereever A==8, and is smaller
    from scipy import stats
    B1=stats.threshold(A, threshmin=8, threshmax=8, newval=0)/8   # make a matrix with ones where there is an 8
    B1=B1[1:-1,1:-1]
    print B1
    
    #another quick way  to make a matrix that's 1 whereever A==8
    B2 = np.zeros((8,8),dtype=np.int)
    B2[A==8]=1
    B2=B2[1:-1,1:-1]
    print B2
    
    # the following would obviously work with either B1 or B2 (which are the same)
    
    print np.multiply(B2,D[1:-1,1:-1])
    

    Output:

    [[1 0 0 0 0 0]
     [1 1 0 0 0 0]
     [0 1 0 0 0 0]
     [0 0 0 1 0 0]
     [0 0 0 1 0 0]
     [0 0 0 0 1 0]]
    [[1 0 0 0 0 0]
     [1 1 0 0 0 0]
     [0 1 0 0 0 0]
     [0 0 0 1 0 0]
     [0 0 0 1 0 0]
     [0 0 0 0 1 0]]
    [[2 0 0 0 0 0]
     [1 2 0 0 0 0]
     [0 3 0 0 0 0]
     [0 0 0 2 0 0]
     [0 0 0 2 0 0]
     [0 0 0 0 3 0]]
    

提交回复
热议问题