【问题标题】:Row exchange in Numpy [duplicate]Numpy中的行交换[重复]
【发布时间】:2014-02-12 19:30:32
【问题描述】:

在 Python 中,我可以通过多重处理来交换 2 个变量;它也适用于列表:

l1,l2=[1,2,3],[4,5,6]
l1,l2=l2,l1
print(l1,l2)
>>> [4, 5, 6] [1, 2, 3]

但是当我想交换 2 行 numpy 数组时(例如在高斯算法中),它失败了:

import numpy as np
a3=np.array([[1,2,3],[4,5,6]])
print(a3)
a3[0,:],a3[1,:]=a3[1,:],a3[0,:]
print(a3)
>>> [[1 2 3]
     [4 5 6]]
    [[4 5 6]
     [4 5 6]]

我认为,出于一个奇怪的原因,两列现在指向相同的值;但事实并非如此,因为a3[0,0]=5 在前面几行之后更改了 a3[0,0] 而不是 a3[1,0]。

我已经找到了解决这个问题的方法:例如a3[0,:],a3[1,:]=a3[1,:].copy(),a3[0,:].copy() 有效。但是任何人都可以解释为什么用 numpy 行进行多次做作的交换会失败吗?我的问题涉及 Python 和 Numpy 的基础工作。

【问题讨论】:

  • 好的,谢谢,这个问题没有在可能重复的列表中自动提出。
  • 没问题 - 我知道它的唯一原因是因为我回答了它。

标签: python numpy


【解决方案1】:

这将按照您的预期方式工作:

a3[[0,1]] = a3[[1,0]]

元组赋值中的两个独立赋值不相互缓冲;一个接一个地发生,导致覆盖你的观察

【讨论】:

  • +1 很好,当您尝试执行 a[[0, 1, 1]] += 1 并且位置 1 处的项目仅增加一次时,这是一件令人讨厌的事情,您可以利用它来交换行。
  • 是的;我花了一段时间才明白这背后的逻辑。对新的 np.add.at 非常满意;事实上,我现在正在用它写一段代码,那曾经是一个非常慢的 python 循环。
  • 对于总和,np.bincount 通常比 np.add.at 快得多,我刚刚尝试过 50 倍:a = np.zeros((1000,), dtype=np.intp); b = np.random.randint(1000, size=100000); c = np.random.randint(1000000, size=100000); In [10]: %timeit np.add.at(a, b, c); 100 loops, best of 3: 19.3 ms per loop; In [11]: %timeit a + np.bincount(b, weights=c, minlength=1000); 1000 loops, best of 3: 451 µs per loop
  • 当然,可读性很差,很难想象这种操作会成为瓶颈的情况。但是,如果您想要原始性能,那么这似乎是可行的方法。
  • 这让我非常惊讶。你会认为 np.add.at 的实现将是可以想象的最基本的循环。也就是说,它也推广到散射到 nd 数组,所以也许这会增加一些开销?但我完全无法想象 40 因子是从哪里来的。
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 2020-06-10
  • 1970-01-01
  • 2016-01-05
  • 2011-06-18
  • 1970-01-01
相关资源
最近更新 更多