Numpy 可变切片大小(可能为零)

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

假设我有一些时间序列数据:

import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
x = np.linspace(0, 10, num=100)
time_series = np.sin(x) + np.random.random(100)
plt.plot(x, time_series)

如果我想将时间序列“延迟”一些,我可以这样做:

delay = 10
x_delayed = x[delay:]
time_series_delayed = time_series[:-delay]

plt.plot(x, time_series, label='original')
plt.plot(x_delayed, time_series_delayed, label='delayed')
plt.legend()

这一切都很好,但我想保持代码干净,同时仍然允许

delay
为零。就目前而言,我得到一个错误,因为切片
my_arr[:-0]
只是评估为
my_arr[:0]
它将始终是空切片,而不是完整数组。

>>> time_series[:-0]
array([], dtype=float64)

这意味着如果我想编码零延迟与原始数组相同的想法,我每次使用切片时都必须特殊情况。这很乏味且容易出错:

# Make 3 plots, for negative, zero, and positive delays
for delay in (0, 5, -5):

    if delay > 0:
        x_delayed = x[delay:]
        time_series_delayed = time_series[:-delay]

    elif delay < 0:
        # Negative delay is the complement of positive delay
        x_delayed = x[:delay]
        time_series_delayed = time_series[-delay:]

    else:
        # Zero delay just copies the array
        x_delayed = x[:]
        time_series_delayed = time_series[:]
    # Add the delayed time series to the plot
    plt.plot(
        x_delayed, 
        time_series_delayed, 
        label=f'delay={delay}',
        # change the alpha to make things less cluttered
        alpha=1 if delay == 0 else 0.3
    )
plt.legend()

我看过 numpy 切片对象和

np._s
,但我似乎无法弄清楚。

是否有一种简洁的/pythonic 方式来编码延迟为零是原始数组的想法?

python numpy indexing slice
1个回答
0
投票

我不知道这是否像人们喜欢的那样整洁,但您可以利用 Python 处理真假的方式,因此如果

i or x
为 0,则
x
等于
i
,但是
 i
如果
i
是任何其他整数。

因此,您可以将条件的各个分支替换为:

time_series_delayed = time_series[:-delay or len(time_series)]

delay
为 0 时,其计算结果为
time_series[:len(time_series)]
time_series
本身相同。

作为快速演示:

time_series = list(range(10))

def f(i):
    return time_series[:-i or len(time_series)]

print(time_series)
for n in (2, 1, 0):
    print(f"{n}: {f(n)}")

打印:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2: [0, 1, 2, 3, 4, 5, 6, 7]
1: [0, 1, 2, 3, 4, 5, 6, 7, 8]
0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
© www.soinside.com 2019 - 2024. All rights reserved.