用奇数索引总和更改元素的符号

时间:2018-03-11 20:38:07

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

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]]]

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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]]]