【问题标题】:Change sign of elements with an odd sum of indices改变具有奇数索引和的元素的符号
【发布时间】:2018-08-19 20:37:00
【问题描述】:

arr 是一个 n 维 numpy 数组。

如何用奇数个索引改变 arr 的每个元素的符号?

例如,arr[0, 1, 2] 需要更改符号,因为它有一个索引总和 0 + 1 + 2 = 3,这是奇数。

当我将arr 转换为一个列表时,我注意到列表中的每个第二个元素都是需要更改符号的元素。

另一个例子:

Original array:

[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]]

Array with signs changed:
[[[ 0  -1  2]
  [ -3  4  -5]
  [ 6  -7  8]]

 [[ -9 10 -11]
  [12 -13 14]
  [-15 16 -17]]

 [[18 -19 20]
  [-21 22 -23]
  [24 -25 26]]]

【问题讨论】:

  • 很不清楚你在问什么。请澄清。
  • 欢迎来到 SO。请提供 minimal reproducible example
  • 你的意思是你想将每个元素乘以 -1 或 +1,+-1 形成一个像棋盘一样的矩阵?
  • 矩阵 a=i,j [1,2,3, 4,5,6, 7,8,9] 例如 a[0][0]=1 a[1][2 ]=6 如果索引的总和是奇数,你必须将它乘以 -1,所以 a[0][0]=1 将是 -1 而 a[1][2]=6 将是 -6
  • 审稿人请注意这个问题已经被一位乐于助人的编辑澄清了。

标签: python python-3.x python-2.7 numpy array-broadcasting


【解决方案1】:

np.negative 比乘法快一点(因为它是 ufunc

N = 5
arr = np.arange(N ** 3).reshape(N, N, N)
%timeit arr.ravel()[1::2] *= -1
%timeit np.negative(arr.ravel()[1::2], out = arr.ravel()[1::2])

The slowest run took 8.74 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 3.39 µs per loop
The slowest run took 5.57 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 3.12 µs per loop

N = 25
arr = np.arange(N ** 3).reshape(N, N, N)
%timeit arr.ravel()[1::2] *= -1
%timeit np.negative(arr.ravel()[1::2], out = arr.ravel()[1::2])

The slowest run took 7.03 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 10.8 µs per loop
The slowest run took 5.27 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 8.63 µs per loop

N = 101
arr = np.arange(N ** 3).reshape(N, N, N)
%timeit arr.ravel()[1::2] *= -1
%timeit np.negative(arr.ravel()[1::2], out = arr.ravel()[1::2])

1000 loops, best of 3: 663 µs per loop
1000 loops, best of 3: 512 µs per loop

【讨论】:

    【解决方案2】:

    hpaulj 的建议大大简化了。

    程序:

    import numpy as np
    
    
    def change_sign(arr):
        """Switch sign of every second element of arr in-place
        Note
        ----
        Modifies the input array (arr).
        """
        # arr.reshape(-1) makes a 1D view of arr
        #
        # [1::2] select every other element of arr,
        #   starting from the 1st element.
        #
        # *= -1 changes sign of selected elements.
    
        arr.reshape(-1)[1::2] *= -1
        return arr
    
    
    def main():
        N = 3
        arr = np.arange(N ** 3).reshape(N, N, N)
        print("original array:")
        print(arr)
        print("change signs")
        print(change_sign(arr))
    
    
    main()
    

    结果:

    original array:
    [[[ 0  1  2]
      [ 3  4  5]
      [ 6  7  8]]
    
     [[ 9 10 11]
      [12 13 14]
      [15 16 17]]
    
     [[18 19 20]
      [21 22 23]
      [24 25 26]]]
    change signs
    [[[  0  -1   2]
      [ -3   4  -5]
      [  6  -7   8]]
    
     [[ -9  10 -11]
      [ 12 -13  14]
      [-15  16 -17]]
    
     [[ 18 -19  20]
      [-21  22 -23]
      [ 24 -25  26]]]
    

    【讨论】:

    • arr.ravel()[1::2]*=-1 怎么样?否定展平视图中的所有其他元素。
    • @hpaulj 简单多了哈哈。
    • 甚至np.negative(arr.ravel()[1::2], out = arr.ravel()[1::2]) 可能更快,但可读性稍差
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2021-11-15
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    相关资源
    最近更新 更多