如何在NumPy中实现带有负索引的离散时间系统表示?
Great question! NumPy's native arrays are designed around 0-based contiguous indexing, so its built-in negative indexing just counts backwards from the end of the array—not exactly what you need for discrete time systems with arbitrary negative indices. While shifting indices is a valid workaround, there are cleaner approaches depending on your needs:
1. Wrap NumPy arrays in a custom class (pure NumPy solution)
You can create a simple wrapper class that handles the index mapping for you. This keeps you within the NumPy ecosystem while abstracting away the offset calculations, so you don't have to manually shift indices every time:
import numpy as np class DiscreteTimeSignal: def __init__(self, index_value_pairs): # Sort indices to ensure consistent ordering in the underlying array sorted_indices = sorted(index_value_pairs.keys()) self.base_index = sorted_indices[0] self.values = np.array([index_value_pairs[idx] for idx in sorted_indices]) def __getitem__(self, idx): if isinstance(idx, int): # Convert discrete time index to array position array_pos = idx - self.base_index if 0 <= array_pos < len(self.values): return self.values[array_pos] raise IndexError(f"Index {idx} out of signal bounds") elif isinstance(idx, slice): # Handle slice operations (e.g., x[-2:1] to get elements from n=-2 to n=0) start = idx.start - self.base_index if idx.start is not None else None stop = idx.stop - self.base_index if idx.stop is not None else None return self.values[slice(start, stop, idx.step)] else: raise TypeError("Only integer or slice indices are supported") def __setitem__(self, idx, value): if isinstance(idx, int): array_pos = idx - self.base_index if 0 <= array_pos < len(self.values): self.values[array_pos] = value return raise IndexError(f"Index {idx} out of signal bounds") raise TypeError("Only integer indices are supported for assignment") # Usage example x = DiscreteTimeSignal({-2: 4, -1: 5, 0: 3, 1: 1}) print(x[-2]) # Output: 4 print(x[0]) # Output: 3 print(x[-1:1]) # Output: [5 3] x[-1] = 6 print(x[-1]) # Output: 6
You can extend this class with additional methods (like convolution or difference operations) to fit your discrete system needs.
2. Use pandas Series (mature tool for indexed sequences)
If you're open to using a library built on top of NumPy, pandas Series is tailor-made for this scenario. It supports arbitrary custom indices (including negative integers) out of the box, and handles index alignment automatically for operations like signal addition or shifting:
import pandas as pd # Create a Series with your discrete time indices x = pd.Series([4, 5, 3, 1], index=[-2, -1, 0, 1]) # Access elements directly by their discrete time index print(x[-2]) # Output: 4 print(x.loc[0]) # Explicit location-based access (safer for custom indices) # Built-in signal operations, like shifting for discrete systems shifted_x = x.shift(1) # Shifts all elements to correspond to x[n-1] print(shifted_x)
This is a great option if you need to perform complex signal operations without building custom logic from scratch.
Why not just use raw NumPy?
NumPy's core strength lies in fast operations on contiguous, regular arrays. Custom non-contiguous or negative-start indices go against this design, so there's no native way to handle this without some form of index mapping. The wrapper class above bridges that gap while staying within NumPy, and pandas provides a production-ready solution if you don't mind the extra dependency.
内容的提问来源于stack exchange,提问作者Zahin Zaman

