避免多个数组到列表转换来创建具有线性细分的对数刻度[关闭]

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

有没有一种方法可以创建具有线性细分的对数刻度,并且列表和 numpy 之间的转换较少?将列表视为数组时,多次更改会导致错误,反之亦然。

def log_linsub(start, end):
    'Creates a log scale from 10**start to 10**end with linear subdivisions.'
    base = np.array(range(1, 10))
    seq = [base*10**val for val in range(start, end)]
    seq = list(np.array(seq).flatten())
    seq.append(10**end)
    return np.array(seq)
python numpy
2个回答
1
投票
def log_linsub(start, end):
    "Creates a log scale from 10**start to 10**end with linear subdivisions."
    return np.unique(
        [
            base * 10**val 
            for val in range(start, end) 
            for base in range(1, 11)
        ]
    )

解释一些重构:

  • 由于您对
    range(1, 10)
    range(start, end)
    进行了迭代,因此可以将其更改为列表理解,使其更加清晰和Pythonic;
  • 您拥有最后一个代码片段的原因是由于其末尾不包含范围,这会导致某些值重复,例如。
    start=1, end=3
    处有 100 和 1000 个值,但您可以使用 np.unique (如果需要 np.array)或
    set(...)
  • 进行重复数据删除

1
投票

使用 numpy 可以非常轻松(快速)地完成此操作。

def log_linsub(start, end):
    a = np.arange(start, end)[:,None]
    b = np.arange(1, 10)
    c = 10**a*b
    return c.ravel()

为了清楚起见,以下是调用

log_linsub(1, 5)
时的中间体:

a
[[1]
 [2]
 [3]
 [4]]

b
[1 2 3 4 5 6 7 8 9]

c
[[   10    20    30    40    50    60    70    80    90]
 [  100   200   300   400   500   600   700   800   900]
 [ 1000  2000  3000  4000  5000  6000  7000  8000  9000]
 [10000 20000 30000 40000 50000 60000 70000 80000 90000]]

速度测试:

>>> %timeit log_linsub_original(1, 5)
10.3 µs ± 621 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit log_linsub_original(1, 1000)
3.89 ms ± 8.54 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> %timeit log_linsub_tiov4d3r(1, 5)
13.1 µs ± 288 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit log_linsub_tiov4d3r(1, 1000)
11.7 ms ± 33.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


>>> %timeit log_linsub_mine(1, 5)
3.23 µs ± 11 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit log_linsub_mine(1, 1000)
18.2 µs ± 137 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

因此,小输入的速度大约快 3 倍,大输入的速度大约快 200 倍。

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