一种更有效的裁剪数组中值的方法?

问题描述 投票:0回答:2

我有以下代码:

import numpy as np

MIN = -3
MAX = 3

def bound(array):
    return np.array([(0 if v == 0 else (MIN if v < 0 else 1)) for v in array]),\
           np.array([(0 if v == 0 else (-1 if v < 0 else MAX)) for v in array])

print(bound(np.array(range(MIN, MAX + 1))))

返回:

(array([-3, -3, -3,  0,  1,  1,  1]), array([-1, -1, -1,  0,  3,  3,  3]))

我的实际数组远大于此,但由从MIN到MAX的整数组成(在这种情况下为-3到3)。

MIN和MAX不应被认为与0对称,但应保持0的值。

是否有更有效/更快的(cpu时间)方法?非常感谢您进行时间比较。

谢谢!

python arrays numpy vectorization broadcast
2个回答
0
投票

我会使用np.select

def bound2(arr):
    pos_neg = arr>0, arr<0
    return (
        np.select(pos_neg, (1,MIN),0),
        np.select(pos_neg, (MAX,-1),0)
    )

测试时间:

# sample data
arr = np.random.randint(-10,10,1000)

%%timeit -n 100
bound(arr)
# 858 µs ± 28.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit -n 100
bound2(arr)
# 59.9 µs ± 4.45 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

0
投票

在np.where中使用

def bound_where(array):
  return np.where(array==0, 0, np.where(array<0, MIN, 1)), \
           np.where(array==0, 0, np.where(array<0, -1, MAX))

与其他方法的比较

Test

方法

  1. 发布方法
  2. 选择方法(@QuangHoang答案的bound2)
  3. 哪里方法(当前答案)

测试代码

arr = np.random.randint(-10,10,1000)
count = 1000
print(f'Posted method: {timeit(lambda:bound(arr), number=count):.4f}')
print(f'Select method: {timeit(lambda:bound2(arr), number=count):.4f}')
print(f'Where mehtod: {timeit(lambda:bound_where(arr), number=count):.4f}')

结果(秒)

Posted method: 6.1951
Select method: 0.3959
Where method: 0.1466

整体上最快的方法

© www.soinside.com 2019 - 2024. All rights reserved.