2

我正在尝试“就地”修改一个 numpy 数组。我有兴趣在原地重新排列数组(而不是返回:重新排列数组的版本)。

这是一个示例代码:

  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()

赋值 ar=arr[[1,0]] 打破了“arr”与传递给函数“modar”的原始数组的对应关系。您可以通过注释/取消注释该行来确认这一点。当然,这是因为必须创建一个新数组。

我如何告诉 python 新数组仍然对应于“arr”?

简单地说,我怎样才能让“modar”重新排列阵列“就地”?

好的..我修改了该代码并将“modarr”替换为:

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

例程“test2”仍然从“modar”获得一个未修改的数组。

4

3 回答 3

1

“对于索引数组的所有情况,返回的是原始数据的副本,而不是切片的视图。”

http://docs.scipy.org/doc/numpy/user/basics.indexing.html

于 2014-10-08T12:53:27.027 回答
0

这是一个额外的解决方案。与Saullo的基本相同。

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()
于 2014-10-09T08:03:58.677 回答
0

在这种情况下,您可以这样做:

  arr2 = arr[[1, 0]]
  arr[...] = arr2[...]

其中临时数组arr2用于存储精美的索引结果。最后一行将数据从原始数组复制arr2到原始数组,保留引用。

注意:确保在您的操作中arr2具有相同的形状arr以避免奇怪的结果......

于 2014-10-08T12:47:08.693 回答