问题
I have a ndarray like this one:
number_of_rows = 3
number_of_columns = 3
a = np.arange(number_of_rows*number_of_columns).reshape(number_of_rows,number_of_columns)
a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
But I want something like this:
array([[0, 100, 101],
       [3, 102, 103],
       [6, 7, 8]])
To do that I want to avoid to do it one by one, I rather prefer to do it in arrays or matrices, because later I want to extend the code. Nothe I have change a submatrix of the initial matrix (in mathematical terms, in terms of this example ndarray). In the example the columns considered are [1,2] and the rows [0,1].
columns_to_keep = [1,2] 
rows_to_keep = [0,1]
My first try was to do:
a[rows_to_keep,:][:,columns_to_keep] = np.asarray([[100,101],[102,103]])
However this doesn't modify the initial a, I am not having any error, so a=
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
So I have implemented a piece of code that goes do the job:
b = [[100, 101],[102, 103]]
for i in range(len(rows_to_keep)):
    a[i,columns_to_keep] = b[i]
Al thought the previous lines do the job I am wondering how to do it slicing and in a faster fashion. Also in a way that with:
columns_to_keep = [0,2] 
rows_to_keep = [0,2]
the desired output is
array([[100, 1, 101],
       [3, 4, 5],
       [102, 7, 103]]).
Many thanks!
回答1:
Indexing with lists like [1,2] is called advanced indexing.  By itself it produces a copy, not a view.  You have to use one indexing expression, not two to assign or change values.  That is a[[1,2],:] is a copy, a[[1,2],:][:,[1,2]] += 100 modifies that copy, not the original a.
In [68]: arr = np.arange(12).reshape(3,4)
Indexing with slices; this is basic indexing:
In [69]: arr[1:,2:]
Out[69]: 
array([[ 6,  7],
       [10, 11]])
In [70]: arr[1:,2:] += 100
In [71]: arr
Out[71]: 
array([[  0,   1,   2,   3],
       [  4,   5, 106, 107],
       [  8,   9, 110, 111]])
Doing the same indexing with lists requires arrays that 'broadcast' against each other.  ix_ is a handy way of generating these:
In [73]: arr[np.ix_([1,2],[2,3])]
Out[73]: 
array([[106, 107],
       [110, 111]])
In [74]: arr[np.ix_([1,2],[2,3])] -= 100
In [75]: arr
Out[75]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
Here's what ix_ produces - a tuple of arrays, one is (2,1) in shape, the other (1,2).  Together they index a (2,2) block:
In [76]: np.ix_([1,2],[2,3])
Out[76]: 
(array([[1],
        [2]]), array([[2, 3]]))
    回答2:
For the continuous rows and columns case, you can use basic slicing like this:
In [634]: a
Out[634]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [635]: b = np.asarray([[100, 101],[102, 103]])
In [636]: a[:rows_to_keep[1]+1, columns_to_keep[0]:] = b
In [637]: a
Out[637]: 
array([[  0, 100, 101],
       [  3, 102, 103],
       [  6,   7,   8]])
来源:https://stackoverflow.com/questions/48464015/writting-in-sub-ndarray-of-a-ndarray-in-the-most-pythonian-way-python-2