问题
I am trying to modify a numpy array "in-place". I am interested in re-arranging the array in-place (instead of return:ing a re-arranged version of the array).
Here is an example code:
from numpy import *
def modar(arr):
arr=arr[[1,0]] # comment & uncomment this line to get different behaviour
arr[:,:]=0
print "greetings inside modar:"
print arr
def test2():
arr=array([[4,5,6],[1,2,3]])
print "array before modding"
print arr
print
modar(arr)
print
print "array now"
print arr
test2()
The assignment ar=arr[[1,0]] breaks the correspondence of "arr" to the original array passed to the function "modar". You can confirm this by commenting/uncommenting that line.. this happens, of course, as a new array has to be created.
How can I tell python that the new array still corresponds to "arr"?
Simply, how can I make "modar" to rearrange the array "in-place"?
Ok.. I modified that code and replaced "modarr" by:
def modar(arr):
# arr=arr[[1,0]] # comment & uncomment this line to get different behaviour
# arr[:,:]=0
arr2=arr[[1,0]]
arr=arr2
print "greetings inside modar:"
print arr
The routine "test2" still gets an unmodified array from "modar".
回答1:
In this case you could do:
arr2 = arr[[1, 0]]
arr[...] = arr2[...]
where the temporary array arr2
is used to store the fancy indexing result. The last line copies the data from arr2
to the original array, keeping the reference.
Note: be sure in your operations that arr2
has the same shape of arr
in order to avoid strange results...
回答2:
"For all cases of index arrays, what is returned is a copy of the original data, not a view as one gets for slices."
http://docs.scipy.org/doc/numpy/user/basics.indexing.html
回答3:
Here is a solution with additional playing around. Basically the same as Saullo's.
from numpy import *
def modar1(arr):
# arr=arr[[1,0]] # (a)
arr[:,:]=arr[[1,0]][:,:] # (b)
print "greetings inside modar:"
print arr
# (a) arr is now referring to a new array .. python does not know if it
# has the same type / size as the original parameter array
# and therefore "arr" does not point to the original parameter array anymore. DOES NOT WORK.
#
# (b) explicit copy of each element. WORKS.
def modar2(arr):
arr2=arr.copy()
arr2=arr2[[1,0]]
# arr=arr2 # (a)
arr[:,:]=arr2[:,:] # (b)
print "greetings inside modar:"
print arr
# (a) same problem as in modar1
# .. it seems that *any* reference "arr=.." will point "arr" to something else as than original parameter array
# and "in-place" modification does not work. DOES NOT WORK
#
# (b) does an explicit copying of each array element. WORKS
#
def modar3(arr):
arr2=arr.copy()
arr2=arr2[[1,0]]
for i in range(arr.shape[0]):
arr[i]=arr2[i]
print "greetings inside modar:"
print arr
# this works, as there is no reference "arr=", i.e. to the whole array
def test2():
#
# the goal:
# give an array "arr" to a routine "modar"
# After calling that routine, "arr" should appear re-arranged
#
arr=array([[4,5,6],[1,2,3]])
print "array before modding"
print arr
print
modar1(arr) # OK
# modar2(arr) # OK
# modar3(arr) # OK
print
print "array now"
print arr
test2()
来源:https://stackoverflow.com/questions/26257067/re-arranging-numpy-array-in-place