Zeroes on specific rows in Python

Question:

I have an array Pe. I want to exclude certain rows mentioned in the list J and ensure the other rows have all zero elements. For example, for Pe[0], J[0]=[0,1] which means 0,1 rows of Pe[0] are to be excluded but 2 row of Pe[0] should contain all zero elements. Similarly, for Pe[1]. But I am getting an error. I also present the expected output.

import numpy as np

Pe = [np.array([[402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [  0.        , 423.81345923,   0.        , 407.01354328,
        419.14952534,   0.        , 316.58460442,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ]]),
np.array([[402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [  0.        , 423.81345923,   0.        , 407.01354328,
        419.14952534,   0.        , 316.58460442,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ]])]  #Entry pressure

J = [[0,1],[2]]



for i in range(0,len(Pe)):
    out = np.zeros_like(Pe[i])
    for j in range(0,len(J)):
        out[i][J[j]] = Pe[i][J[j]]
    print([out])

The error is

in <module>
    out[i][J[j]] = Pe[i][J[j]]

ValueError: shape mismatch: value array of shape (2,12)  could not be broadcast to indexing result of shape (2,)

The expected output is

[np.array([[402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [  0.        , 423.81345923,   0.        , 407.01354328,
        419.14952534,   0.        , 316.58460442,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [0. ,            0.        ,   0. ,          0. ,
          0.        , 0. ,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ]]),
np.array([[0. ,   0.        , 0. , 0. ,
          0.        , 0. ,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [  0.        , 0. ,   0.        , 0. ,
        0. ,   0.        , 0.,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ],
       [402.93473651,   0.        , 230.97804127, 407.01354328,
          0.        , 414.17017965,   0.        ,   0.        ,
          0.        ,   0.        ,   0.        ,   0.        ]])]
Asked By: AEinstein

||

Answers:

out = []
for arr, ind in zip(Pe, J):
    x = np.zeros_like(arr)
    x[ind] = arr[ind]
    out.append(x)
Answered By: Chrysophylaxs

Using lists and loops in Numpy is often an anti-pattern, and that is the case here. You should be using vectorised operations throughout. J is jagged so you need to reinterpret it as a boolean indexer. Also, Pe should not start with repeated dimensions; it should start as a single two-dimensional array without a list.

import numpy as np

Pe = np.array([[402.93473651,   0.        , 230.97804127, 407.01354328,
                  0.        , 414.17017965,   0.        ,   0.        ,
                  0.        ,   0.        ,   0.        ,   0.        ],
               [  0.        , 423.81345923,   0.        , 407.01354328,
                419.14952534,   0.        , 316.58460442,   0.        ,
                  0.        ,   0.        ,   0.        ,   0.        ],
               [402.93473651,   0.        , 230.97804127, 407.01354328,
                  0.        , 414.17017965,   0.        ,   0.        ,
                  0.        ,   0.        ,   0.        ,   0.        ]])

J = np.ones((2, Pe.shape[0]), dtype=bool)
J[0, 0:2] = 0
J[1, 2] = 0

Pe_indexed = np.tile(Pe, (J.shape[0], 1, 1))
Pe_indexed[J, :] = 0

Pe_indexed will now be a proper three-dimensional matrix, no lists.

Answered By: Reinderien
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.